发出POST请求时,@ RequestBody给出空的JsonObject [英] @RequestBody gives empty JsonObject when making a POST Request

查看:1387
本文介绍了发出POST请求时,@ RequestBody给出空的JsonObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下方法:

@RequestMapping(value = "/app/write", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public
@ResponseBody
Status writeBuildData(@RequestBody JsonObject templateDataJSON){}

基本上,我发出发送JSON的Ajax POST请求,结果总是得到一个空的JsonObject {}

Basically I make an Ajax POST request sending JSON, I always get an empty JsonObject {} as a result

JsonObject templateDataJSON = "{}";

但是,如果我使用String而不是JsonObject,则会得到正确的值.

But if I use String instead of JsonObject, I get the correct value.

此应用是使用 Spring Mvc 4.1.4 制作的.

依赖项:

compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
compile 'com.google.code.gson:gson:2.3.1'

有什么主意我想念什么,为什么为什么不注入JsonObject却总是给我{}?

Any idea what I am missing and why the JsonObject doesn't get injected and always gives me {}?

推荐答案

Spring不再支持Jackson 1作为消息转换器实现.

Spring no longer supports Jackson 1 as a message converter implementation.

所以你的

compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'

实际上对Spring毫无意义.

is actually meaningless to Spring.

您的

compile 'com.google.code.gson:gson:2.3.1'

将导致Spring使用GsonHttpMessageConverter,并且基本上会使用

will cause Spring to use GsonHttpMessageConverter and, basically, do

String json = "{\"random\":\"42\"}";
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);

JsonObject是Gson类型. Gson意识到了这一点,并且知道如何将JSON对象json反序列化到其中.这将正常工作并生成一个JsonObject,其值为

JsonObject is a Gson type. Gson is aware of it and knows how to deserialize JSON object json into it. This will work correctly and will generate a JsonObject which has a value of

{"random":"42"}

由于您说的是空的JsonObject,所以我只能假设您的类路径中有Jackson 2.

Since you're saying that you're getting an empty JsonObject, I can only assume that you have Jackson 2 on your classpath.

如果在类路径上都存在GsonHttpMessageConverter,则Spring在GsonHttpMessageConverter之前注册Jackson HttpMessageConverterMappingJackson2HttpMessageConverter.

Spring registers the Jackson HttpMessageConverter, MappingJackson2HttpMessageConverter, before the GsonHttpMessageConverter if both are present on the classpath.

有了Jackson,Spring基本上会反序列化您的请求正文

With Jackson, Spring would have deserialized your request body basically as such

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JsonObject jsonObject = mapper.readValue(json, JsonObject.class);

您会注意到的结果

{}

这是因为Jackson对JsonObject类型一无所知,因此必须动态构建反序列化策略.该策略取决于Jackson定义为二传手(用于反序列化的上下文)的属性或任何带有@JsonProperty注释的属性,而JsonObject显然没有.因此,它基本上认为类型JsonObject没有任何属性(或者可能没有出现在您的自定义JSON内容中).这样,由于它会忽略任何未知属性(这会导致其引发异常),因此它仅返回一个新的空JsonObject对象.

This is because Jackson knows nothing about the type JsonObject so it has to dynamically build a deserialization strategy. That strategy depends on properties which Jackson defines as setters (for the context of deserialization) or anything annotated with @JsonProperty, which obviously JsonObject doesn't have. So it basically thinks the type JsonObject doesn't have any properties (or maybe none that appear in your custom JSON content). As such, and because it ignores any unknown properties (which would have caused it to throw exceptions), it simply returns a new, empty JsonObject object.

一种解决方案是从类路径中删除Jackson 2.另一种解决方案是按所需顺序显式添加HttpMessageConverter实例.

One solution is to remove Jackson 2 from the classpath. Another solution is to explicitly add HttpMessageConverter instances in the order you want.

这篇关于发出POST请求时,@ RequestBody给出空的JsonObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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