在 SpringMVC 中使用 @ResponseBody 返回 JsonObject [英] Returning JsonObject using @ResponseBody in SpringMVC

查看:34
本文介绍了在 SpringMVC 中使用 @ResponseBody 返回 JsonObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 SpringMVC 项目中为 JSON 使用新的 Java API (JSR 353).

I am using the new Java API (JSR 353) for JSON in a SpringMVC project.

这个想法是生成一些 Json 数据并将其返回给客户端.我的控制器看起来有点像这样:

The idea is to generate some piece of Json data and have it returned to the client. The controller I have look somewhat like this:

@RequestMapping("/test")
@ResponseBody
public JsonObject test() {
        JsonObject result = Json.createObjectBuilder()
                .add("name", "Dade")
                .add("age", 23)
                .add("married", false)
                .build();
        return result;
    }

当我访问它时,我得到的不是预期的 JSON 表示,而是这些:

And when I access this, instead of getting the expected representation of the JSON, I get these instead:

{"name":{"chars":"Dade","string":"Dade","valueType":"STRING"},"age":{"valueType":"NUMBER","integral":true},"married":{"valueType":"FALSE"}}

这是为什么?到底是怎么回事?以及如何让它正确返回预期的 JSON?

Why is this? What is going on? And how do I make it returned the expected JSON properly?

推荐答案

当您意识到新的 JSR 353 API 没有特殊的 HandlerMethodReturnValueHandler 时,答案很简单.相反,在这种情况下,RequestResponseBodyMethodProcessor(用于 @ResponseBody)使用 MappingJackson2HttpMessageConverter 来序列化处理程序方法的返回值.

The answer is pretty simple when you realize there is no special HandlerMethodReturnValueHandler for the new JSR 353 API. Instead, in this case, the RequestResponseBodyMethodProcessor (for @ResponseBody) uses a MappingJackson2HttpMessageConverter to serialize the return value of your handler method.

在内部,MappingJackson2HttpMessageConverter 使用 ObjectMapper.默认情况下,ObjectMapper 使用类的 getter 将对象序列化为 JSON.

Internally, the MappingJackson2HttpMessageConverter uses an ObjectMapper. By default, the ObjectMapper uses the getters of a class to serialize an object to JSON.

假设您正在使用 Glassfish 的 JSR 353 提供程序实现,这些类是 org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImplorg.glassfish.json.JsonStringImpl,和org.glassfish.json.JsonNumberImpljavax.json.JsonValue$3(值 FALSE 的匿名类).

Assuming you are using Glassfish's provider implementation of the JSR 353, those classes are org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl, org.glassfish.json.JsonStringImpl, and org.glassfish.json.JsonNumberImpl, and javax.json.JsonValue$3 (an anonymous class for the value FALSE).

因为 JsonObjectImpl(你的结果,即 root,对象)是一个 Map(特殊类型),ObjectMapper 将地图的条目序列化为JSON 键值对元素,其中 Map 键为 JSON 键,Map 值为 JSON 值.对于密钥,它工作正常,序列化为 nameagemarried.对于值,它使用我上面提到的类及其各自的 getter.例如,org.glassfish.json.JsonStringImpl 实现为

Because JsonObjectImpl (your result, ie. root, object) is a Map (special type), ObjectMapper serializes the map's entries as JSON key-value pair elements, where the Map key is the JSON key, and the Map value is the JSON value. For the key, it works fine, serializing as name, age, and married. For the value, it uses the classes I mentioned above and their respective getters. For example, org.glassfish.json.JsonStringImpl is implemented as

final class JsonStringImpl implements JsonString {

    private final String value;

    public JsonStringImpl(String value) {
        this.value = value;
    }

    @Override
    public String getString() {
        return value;
    }

    @Override
    public CharSequence getChars() {
        return value;
    }

    @Override
    public ValueType getValueType() {
        return ValueType.STRING;
    }
    ...
}

ObjectMapper 因此使用 Java Bean getter 序列化 JsonStringImpl 对象(即 Map Entry 的值),如

ObjectMapper therefore uses the Java Bean getters to serialize the JsonStringImpl object (that is the Map Entry's value), as

{"chars":"Dade","string":"Dade","valueType":"STRING"}

同样适用于其他领域.

如果您想正确编写 JSON,只需返回一个 String.

If you want to correctly write the JSON, simply return a String.

@RequestMapping("/test", produces="application/json")
@ResponseBody
public String test() {
        JsonObject result = Json.createObjectBuilder()
                .add("name", "Dade")
                .add("age", 23)
                .add("married", false)
                .build();
        return result.toString();
}

或者自己制作HandlerMethodReturnValueHandler,稍微复杂一点,但更有收获.

Or make your own HandlerMethodReturnValueHandler, a little more complicated, but more rewarding.

这篇关于在 SpringMVC 中使用 @ResponseBody 返回 JsonObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆