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

查看:271
本文介绍了在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?

推荐答案

当你意识到没有特殊的 HandlerMethodReturnValueHandler 用于新的JSR 353 API。相反,在这种情况下, 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 $ JsonObjectImpl org.glassfish.json.JsonStringImpl
org.glassfish.json.JsonNumberImpl javax.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,object)是 Map (特殊类型), ObjectMapper 将地图的条目序列化为JSON键值对元素,其中Map键是JSON键,Map值是JSON值。对于密钥,它工作正常,序列化为名称年龄已结婚。对于该值,它使用我上面提到的类和它们各自的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"}

这同样适用于其他字段。

The same applies for the other fields.

如果你想要正确编写JSON,只需返回字符串

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天全站免登陆