我在Grails 2.4.4中构建REST API并依赖RestfulController来处理基本的CRUD类型功能。前端是在AngularJS 1.3中构建的,大部分Angular的$资源和Grails RestfulController完美地工作,并且不要求我编写很多样板代码。我有一个主要问题,即当我将JSON从Angular发布到Grails时,具有hasMany关系的域对象不会按预期绑定。
例如,请使用以下域对象:
class Task {
String name
//auto timestamps
Date dateCreated
Date lastUpdated
static hasMany = [filters:TaskFilter]
static constraints = {
}
}
class TaskFilter {
String filterMetaData
static belongsTo = [task:Task]
static constraints = {
task column: 'task_id'
}
}
当我像这样发布一个像这样的对象时:
{name: "Task 1", filters: [{filterMetaData:'some-meta-data'}]}
我在Grails中收到以下错误:
| Error 2015-02-10 17:41:34,619 [http-bio-8080-exec-5] ERROR errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [POST] /api/studies/1/tasks
Stacktrace follows:
Message: null
Line | Method
->> 99 | $tt__save in grails.rest.RestfulController
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 198 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . . . . . in grails.plugin.cache.web.filter.AbstractFilter
| 104 | processFilterChain in com.odobo.grails.plugin.springsecurity.rest.RestTokenValidationFilter
| 71 | doFilter . . . . . in ''
| 53 | doFilter in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 122 | doFilter . . . . . in com.odobo.grails.plugin.springsecurity.rest.RestAuthenticationFilter
| 82 | doFilter in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 63 | doFilter . . . . . in com.odobo.grails.plugin.springsecurity.rest.RestLogoutFilter
| 82 | doFilter in com.brandseye.cors.CorsFilter
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . in java.lang.Thread
我不确定这个错误是怎么回事,因为它很模糊但是Task和TaskFilter被回滚并且没有保存任何东西。
奇怪的是,如果我从TaskFilter中删除这行代码:
static belongsTo = [task:Task]
一切正常但除此之外,这迫使我有一个task_task_filter连接表,而不是在task_filter表中更容易grok task_id列。
过去几天我一直在这里以及各种论坛,博客和邮件列表上阅读帖子,但还没有找到解决方案。大多数帖子都比较旧,所以我无法判断它们是否适用,但有几个只是说#34;你不能使用Grails"来绑定JSONArray。这似乎很奇怪,因为它是任何中等复杂数据模型的常见要求。
无论如何 - 如果有人能指出一些具体的和现实的东西要么说'#34;你不能做到"或者如何真正处理这种情况我非常感激。如果可能的话,我宁愿避免编写自定义解析代码来管理它,因为RestfulController的其余部分就像魅力一样。此外,如果有任何解释,为什么这个工作,当我删除关系的belongsTo方面也许这将有助于我理解这里发生了什么。
以防万一有人想知道我的RestfulController子类是这样的:
class TaskController extends RestfulController<Task> {
static responseFormats = ['json', 'xml']
TaskController() {
super(Task)
}
}
答案 0 :(得分:0)
经过与grails开发团队的多次讨论后,我被告知我对这应该如何工作的理解并不是Grails的工作方式。我假设(错误地),因为数据绑定将TaskFilter添加到Task,它的行为就好像在Task上调用了addToFilters(),但是对于那些不是如何创建集合的东西。我不知道该集合究竟是什么,但它确实不保存它们。
JIRA已被关闭为“表现得如预期”。
我的解决方法是在我的TaskController
中的以下内容@Override
protected Task createResource() {
Task task = super.createResource()
if (task.filters) {
task.filters.each {filter ->
task.addToFilters(filter)
}
}
task
}
不幸的是,基于RestfulController的应用程序中的任何关联都需要这种类型的代码来处理嵌套资源。我仍然认为Grails应该在框架中处理这个问题,如果我能抽出时间来处理它,我可以尝试将该功能添加到代码中。