首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当JSON对象中缺少" class“属性时,JSON上的数据绑定到域类不正确

当JSON对象中缺少" class“属性时,JSON上的数据绑定到域类不正确
EN

Stack Overflow用户
提问于 2011-12-21 16:51:45
回答 1查看 950关注 0票数 0

当我试图将一个JSON有效负载绑定到一个对另一个域对象具有可空引用的现有域对象时,如果绑定的JSON表示引用为null,则绑定失败。这将导致持久性尝试在此错误中失败:

代码语言:javascript
运行
复制
| Error 2011-12-21 10:21:24,202 ["http-bio-8080"-exec-3] ERROR hibernate.AssertionFailure  - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
Message: null id in server.Uploader entry (don't flush the Session after an exception occurs)
    Line | Method
->>  105 | update    in server.SessionController
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run       in java.lang.Thread
| Error 2011-12-21 10:21:24,206 ["http-bio-8080"-exec-3] ERROR errors.GrailsExceptionResolver  - AssertionFailure occurred when processing request: [POST] /Server/session/2
null id in server.Uploader entry (don't flush the Session after an exception occurs). Stacktrace follows:
Message: null id in server.Uploader entry (don't flush the Session after an exception occurs)
    Line | Method
->>  105 | update    in server.SessionController
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    722 | run       in java.lang.Thread

下面是有问题的域对象:

代码语言:javascript
运行
复制
class Session {
    DateTime dateCreated
    DateTime lastUpdated
    String ip
    String state

    static hasOne = [uploader:Uploader]
    static constraints = {
        ip blank: false
        state blank: false
        uploader nullable: true, unique: true
    }
}

class Uploader {
    DateTime dateCreated
    DateTime lastUpdated
    Session session
    String firstName
    String lastName
    String organization
    String phoneNumber
    String emailAddress

    static constraints = {
        firstName blank: false
        lastName blank: false
        organization blank: false
    }
}

下面是抛出错误的控制器代码:

代码语言:javascript
运行
复制
def update() {
    def sessionInstance = Session.get(params.id)
    if (!sessionInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'session.label', default: 'Session'), params.id])
        redirect(action: "list")
        return
    }

    if (params.version) {
        def version = params.version.toLong()
        if (sessionInstance.version > version) {
            sessionInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                    [message(code: 'session.label', default: 'Session')] as Object[],
                    "Another user has updated this Session while you were editing")
            render(view: "edit", model: [sessionInstance: sessionInstance])
            return
        }
    }

    sessionInstance.properties = params

    if (!sessionInstance.save(flush: true)) {      // <---- Error thrown here
        render(view: "edit", model: [sessionInstance: sessionInstance])
        return
    }

    flash.message = message(code: 'default.updated.message', args: [message(code: 'session.label', default: 'Session'), sessionInstance.id])
    redirect(action: "show", id: sessionInstance.id)
}

这是引起问题的JSON有效负载:

代码语言:javascript
运行
复制
{
"id":2,
"dateCreated":"2011-12-21T09:33:33-06:00",
"ip":"127.0.0.1",
"lastUpdated":"2011-12-21T09:33:33-06:00",
"state":"closed",
"uploader":null
}

但是这个JSON有效负载工作得很好:

代码语言:javascript
运行
复制
{
"class": "server.Session",
"id":2,
"dateCreated":"2011-12-21T09:33:33-06:00",
"ip":"127.0.0.1",
"lastUpdated":"2011-12-21T09:33:33-06:00",
"state":"closed",
"uploader":null
}

所发生的情况是会话的uploader属性被设置为"server.Uploader : null"。这是继.dump()之后的sessionInstance对象的sessionInstance.properties = params

代码语言:javascript
运行
复制
<server.Session@713c6968 dateCreated=2011-12-21T09:33:33.000-06:00 lastUpdated=2011-12-21T09:33:33.000-06:00 ip=127.0.0.1 state=closed errors=grails.validation.ValidationErrors: 0 errors id=2 version=1 uploader=server.Uploader : null>

"class": "server.Session"属性在JSON有效负载中时,一切都正常工作,但是没有它,一切都会崩溃。我认为数据绑定能够处理这个问题,因为它可以很好地映射其余的属性,但是对于引用来说,它似乎失败了。

最后,我遇到这种情况的原因是,我正在尝试使用REST构建格里芬客户机,而且当HTTPBuilder将原始JSON响应转换为net.sf.json.JSONObject时,它似乎正在剥离"class": "server.Session",因为跨线响应中有属性,但是net.sf.json.JSONObject的转储没有,后续的JSON请求有效负载也没有。

  1. :在没有JSON对象的“类”属性时,Grails数据绑定是一个bug吗?
  2. 是HTTPBuilder如何解析JSON响应的bug吗?
  3. 是HTTPBuilder如何从net.sf.json.JSONObject输出JSON的错误吗?
  4. --我只是做了什么完全错误的事情吗?

G 224

更新

我还发现了一些额外的信息:

删除唯一约束的

  1. 不会更改行为
  2. ,如果uploader字段为非空,并且绑定的JSON对象试图将其设置为null,则属性不会更改(并且不会发生错误)。但是,如果"class": "server.Session"属性在绑定的JSON有效负载中,它将按预期更改为null .
EN

回答 1

Stack Overflow用户

发布于 2011-12-21 18:12:52

IIRC的JSONObject将自动删除特殊属性,如"class“和"metaClass”(在POGO的情况下)。您可以通过JsonConfig实例来配置这种行为,但是我不知道HTTPBuilder是否允许您在适当的时候注入这样的实例。

另一种方法(类似于恶意)是以不同的名称(比如clazz)发送类属性值,Json不会删除这个名称。您必须在Grails侧注册一个过滤器,以便将'clazz‘映射到'class’中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8593377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档