java 在 Spring 中读取 Content-Type 应用程序/json

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30844228/
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:44:27  来源:igfitidea点击:

Reading Content-Type application/json in Spring

javajsonspringspring-mvcspring-boot

提问by Gregor

Like in trying-to-use-spring-boot-rest-to-read-json-string-from-postI want to read a json payload from a POST request in a Spring RestController. Using the content type "text/plain" there is no problem, but with "application/json" the deserialization fails and I get a MessageNotReadable exception. But actually the content couldn't be simpler, it is just an empty json object "{}". Could it be that a required converter is missing? I use Spring Root version 1.2.3.RELEASE.

就像在try-to-use-spring-boot-rest-to-read-json-string-from-post 中一样,我想从 Spring RestController 中的 POST 请求中读取 json 有效负载。使用内容类型“text/plain”没有问题,但使用“application/json”反序列化失败,我得到一个 MessageNotReadable 异常。但实际上内容再简单不过了,它只是一个空的json对象“{}”。可能是缺少所需的转换器吗?我使用 Spring Root 版本 1.2.3.RELEASE。

Coding Example

编码示例

@RequestMapping(value = "/deepdefinitions", method = POST, headers = "Accept=application/json")
@ResponseBody
public Definitions createOrUpdateDefinitions(HttpEntity<String> httpEntity) throws IOException { ... }

Curl Call

卷曲呼叫

curl -H  "Content-type: application/json" -X POST -d '{}' http://localhost:8080/deepdefinitions

Error

错误

{"timestamp":1434397457853,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Could not read JSON: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: org.apache.catalina.connector.CoyoteInputStream@122f9ce3; line: 1, column: 1]; nested exception is com.fasterxml.Hymanson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: org.apache.catalina.connector.CoyoteInputStream@122f9ce3; line: 1, column: 1]","path":"/deepdefinitions"}

回答by randominstanceOfLivingThing

From Spring REST guide:

来自Spring REST 指南

The Acceptand Content-TypeHTTP headers can be used to describe the content being sent or requested within an HTTP request. The client may set Acceptto application/jsonif it is requesting a response in JSON. Conversely, when sending data, setting the Content-Typeto application/xmltells the client that the data being sent in the request is XML.

AcceptContent-TypeHTTP标头可用于描述内容的HTTP请求内正在发送或请求。客户端可以设置Acceptapplication/json是否请求 JSON 格式的响应。相反,在发送数据时,设置Content-Typeapplication/xml告诉客户端请求中发送的数据是 XML。

It appears your Controller is processing only Accept header:

看来您的控制器只处理 Accept 标头:

@RequestMapping(value = "/deepdefinitions", method = POST, headers = "Accept=application/json")

You need to change it to:

您需要将其更改为:

@RequestMapping(value = "/deepdefinitions", method = POST, headers = "Accept=application/json, Content-type=application/json")

There are also consumesand produceselementsavailable in @RequestMappingannotation.

注释中还有可用的consumesproduces元素@RequestMapping

The Spring MVC documentationrecommends:

Spring MVC的文件建议:

Although you can match to Content-Typeand Acceptheader values using media type wild cards (for example "content-type=text/*" will match to "text/plain" and "text/html"), it is recommended to use the consumesand producesconditions respectively instead. They are intended specifically for that purpose.

尽管您可以使用媒体类型通配符匹配Content-TypeAccept标题值(例如“content-type=text/*”将匹配“text/plain”和“text/html”),但建议分别使用consumesproduces条件反而。它们专门用于该目的。



Going by your related post, you should change your method signature to:

根据您的相关帖子,您应该将方法签名更改为:

@ResponseBody
public Definitions createOrUpdateDefinitions(@RequestBody String value, HttpEntity<String> httpEntity) throws IOException

I think you should also change you curl command as below. This is because {}(JavaScript Object literal) would map to a object and to map to a String you should use a empty string ''literal.

我认为你也应该改变你的 curl 命令,如下所示。这是因为{}(JavaScript Object literal) 会映射到一个对象,而要映射到 String,您应该使用空字符串''文字。

curl -H "Content-type: application/json" -X POST -d '' http://localhost:8080/deepdefinitions