Grails 3 响应方法不使用定义的 JSON 编组器格式

Posted

技术标签:

【中文标题】Grails 3 响应方法不使用定义的 JSON 编组器格式【英文标题】:Grails 3 respond method doesn't use defined JSON marshaller format 【发布时间】:2017-09-07 12:31:40 【问题描述】:

我目前使用

为每个资源定义自定义 API 响应
JSON.registerObjectMarshaller(Something)  ... 

在 BootStrap init 闭包内。

使用render something as JSON 给了我想要的输出。域类的一些属性根据编组器设置被过滤掉。

但是,当我使用 respond 方法时,它不使用 marshaller 格式,而是显示域类的所有属性。

有没有办法让 respond 使用编组器设置的所需输出?

Grails 版本:3.2.8

更新:

使用 rest-api 配置文件时似乎出现了问题。

【问题讨论】:

我认为做类似事情的新“grails 方式”是使用他们的 Json 视图。我在几个不同的 grails 项目中使用自定义对象编组器,我让它们都使用渲染函数而不是响应函数。你有理由使用响应与渲染吗? @zypherman 如果我使用响应,代码会更少。并且因为其他项目中的一些现有代码使用了response。我想知道是否可以以相同的方式使用 Json 视图,包括用于其中包含嵌套资源的资源? 看起来你可以做一个深度渲染来渲染嵌套资源。 JSON 视图文档不是非常详细,但我相信您能够指定您希望输出的外观与您在对象封送器闭包中的执行方式非常相似。 【参考方案1】:

当您使用配置文件创建 grails 应用程序时会发生此问题:rest-api。 更准确地说,问题是由两个条件引起的:

    在 build.gradle 中应用插件:“org.grails.plugins.views-json”。 views/object/_object.gson 存在

如果你深入“响应”,你会发现:

renderer = registry.findRenderer(mimeType, value)

此时,renderer(Renderer)实例的具体类取决于是否满足上述条件。

如果满足以上条件 => grails.plugin.json.renderer.JsonViewJsonRenderer 否则 => org.grails.plugins.web.rest.render.json.DefaultJsonRenderer

(如果您为某个类定义了自定义 json 渲染器类,则可能会在此处返回该渲染器。自定义 json 渲染器与自定义 marshaller 完全不同,因此请忽略此处的情况。)

当renderer == DefaultJsonRenderer时,渲染逻辑最终转到:

DefaultJsonRenderer.groovy:

protected void renderJson(T object, RenderContext context) 
    JSON converter
    if (namedConfiguration) 
        JSON.use(namedConfiguration) 
            converter = object as JSON
        
     else 
        converter = object as JSON
    
    renderJson(converter, context)

所以,这会导致与“render --- as JSON”相同的结果。

另一方面,当渲染器 == JsonViewJsonRenderer, 它不是指JSON.registerObjectMarshaller创建的自定义注册编组器,而是指gson视图。

因此,如果您想启用自定义编组器并保留 gson 视图功能, 快速解决方案是删除 _object.gson。

如果你去掉了views-json插件,应用中就没有人可以实现gson view了,以后可能会造成不便。

【讨论】:

那我应该停止使用json视图吗? 所以问题是rest-api配置文件生成了文件grails-app/views/object/_object.json,它被用来代替注册的json marshaller。解决方案是删除该文件。这样,响应应该可以正常工作,对@hitokun-s? 是的,你是对的。我在相同情况的演示应用程序中检查了这一点。请在您的应用中尝试。 @toshi 这个解决方案在 grails 4.0.1 中对我不起作用。我删除了 _object.json,但我的响应仍然有渲染器 == JsonViewJsonRenderer。我的所有响应调用都需要渲染器 == DefaultJsonRenderer。关于如何使其适用于 4.0.1 的任何想法。

以上是关于Grails 3 响应方法不使用定义的 JSON 编组器格式的主要内容,如果未能解决你的问题,请参考以下文章

Grails REST 控制器响应不正确的内容类型

JSON的Grails 2.4命名配置不起作用

在使用“as JSON”呈现响应时更改 JSON 响应的 Content-Type

在“呈现为 JSON”之后添加自定义标头以响应

Grails REST Client Builder 在处理来自 Jersey Web 服务的响应时收到 JSON 反序列化错误

如何在Grails 3.3.10中使用自定义约束?