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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30383139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:01:51  来源:igfitidea点击:

@RequestBody gives empty JsonObject when making a POST Request

javajsonspringHymanson

提问by Mythul

I have the following method:

我有以下方法:

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

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

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

JsonObject templateDataJSON = "{}";

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

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

This app is made with Spring Mvc 4.1.4.

这个应用程序是用Spring Mvc 4.1.4 制作的

Dependencies:

依赖项:

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

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

知道我缺少什么以及为什么JsonObject没有被注入并且总是给我{}吗?

回答by Sotirios Delimanolis

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

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

So your

所以你的

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

is actually meaningless to Spring.

实际上对Spring毫无意义。

Your

你的

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

will cause Spring to use GsonHttpMessageConverterand, basically, do

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

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

JsonObjectis 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 JsonObjectwhich has a value of

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

{"random":"42"}

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

既然你说你得到了一个空的JsonObject,我只能假设你的类路径上有 Hymanson 2。

Spring registers the Hymanson HttpMessageConverter, MappingHymanson2HttpMessageConverter, before the GsonHttpMessageConverterif both are present on the classpath.

Spring在类路径中存在 if之前注册 Hymanson HttpMessageConverter, 。MappingHymanson2HttpMessageConverterGsonHttpMessageConverter

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

对于 Hymanson,Spring 基本上会反序列化您的请求主体

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

which you'll note results in

你会注意到结果

{}

This is because Hymanson knows nothing about the type JsonObjectso it has to dynamically build a deserialization strategy. That strategy depends on properties which Hymanson defines as setters (for the context of deserialization) or anything annotated with @JsonProperty, which obviously JsonObjectdoesn't have. So it basically thinks the type JsonObjectdoesn'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 JsonObjectobject.

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

One solution is to remove Hymanson 2 from the classpath. Another solution is to explicitly add HttpMessageConverterinstances in the order you want.

一种解决方案是从类路径中删除 Hymanson 2。另一种解决方案是HttpMessageConverter按您想要的顺序显式添加实例。

回答by Rafael

The explanation why it fails is perfectly done at Sotirios Delimanolis answer.

Sotirios Delimanolis answer 完美地解释了它失败的原因。

However there is a workaround:

但是有一个解决方法:

@RequestBody Map<String, String> json

That way you can continue using Hymanson HttpMessageConverter and work with custom objects in payload.

这样您就可以继续使用 Hymanson HttpMessageConverter 并处理负载中的自定义对象。

回答by Dawid D

What represents JsonObject ? You should use object that represent json you sending. Something like

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

public class Foo {
    String foo;
    String bar;
}

instead JsonObject

而是 JsonObject

and json like :

和 json 一样:

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