@RequestBody在发出POST请求时给出空的JsonObject

时间:2015-05-21 19:53:48

标签: java json spring jackson

我有以下方法:

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

基本上我发送了一个发送JSON的Ajax POST请求,因此我总是得到一个空的JsonObject {}

JsonObject templateDataJSON = "{}";

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

此应用程序由 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没有被注射并总是给我{}

5 个答案:

答案 0 :(得分:7)

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

所以你的

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

对Spring来说实际上毫无意义。

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

将导致Spring使用GsonHttpMessageConverter,基本上,

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

JsonObject是Gson类型。 Gson知道它并且知道如何将JSON对象json反序列化到它中。这将正常工作,并将生成JsonObject,其值为

{"random":"42"}

既然你说你得到一个空的JsonObject,我只能假设你的班级路径上有杰克逊2。

如果类似路径中存在杰克逊HttpMessageConverter,那么Spring会在MappingJackson2HttpMessageConverter之前注册GsonHttpMessageConverterObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); JsonObject jsonObject = mapper.readValue(json, JsonObject.class);

对于杰克逊来说,Spring会基本上将您的请求主体反序列化为

{}

您将注意到

JsonObject

这是因为Jackson对类型@JsonProperty一无所知,因此必须动态构建反序列化策略。该策略取决于Jackson定义为setter(针对反序列化的上下文)或使用JsonObject注释的任何内容的属性,显然JsonObject没有。因此它基本上认为类型JsonObject没有任何属性(或者可能没有出现在您的自定义JSON内容中)。因此,并且因为它忽略了任何未知属性(这会导致它抛出异常),它只返回一个新的空HttpMessageConverter对象。

一种解决方案是从类路径中删除Jackson 2。另一种解决方案是按照您想要的顺序显式添加{{1}}个实例。

答案 1 :(得分:0)

什么代表JsonObject?你应该使用代表你发送的json的对象。像

这样的东西
public class Foo {
    String foo;
    String bar;
}

代替JsonObject

和json喜欢:

{
  "foo" : "val",
  "bar" : "val"
}

答案 2 :(得分:0)

为什么失败的解释完全由Sotirios Delimanolis的答案完成。

但是有一种解决方法:

@RequestBody Map<String, String> json

这样,您就可以继续使用Jackson HttpMessageConverter并在有效负载中使用自定义对象。

答案 3 :(得分:0)

这很简单

@PostMapping
public ResponseEntity<?> yourMethod(@RequestBody String data) {
    JSONObject jsonObject = new JSONObject(data);
    //use the jsonObject now
}

答案 4 :(得分:-1)