Reading Content-Type application/json in Spring
From Spring REST guide:
The
Accept
andContent-Type
HTTP headers can be used to describe the content being sent or requested within an HTTP request. The client may setAccept
toapplication/json
if it is requesting a response in JSON. Conversely, when sending data, setting theContent-Type
toapplication/xml
tells the client that the data being sent in the request is XML.
It appears your Controller is processing only Accept header:
@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 consumes
and produces
elements available in @RequestMapping
annotation.
The Spring MVC documentation recommends:
Although you can match to
Content-Type
andAccept
header values using media type wild cards (for example "content-type=text/*" will match to "text/plain" and "text/html"), it is recommended to use theconsumes
andproduces
conditions respectively instead. They are intended specifically for that purpose.
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 -H "Content-type: application/json" -X POST -d '' http://localhost:8080/deepdefinitions
Gregor
Updated on June 28, 2022Comments
-
Gregor almost 2 years
Like in trying-to-use-spring-boot-rest-to-read-json-string-from-post I 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.
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.jackson.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"}
-
Darshan almost 9 yearsYou should use headers = "Accept=application/json" in '@RequestMapping' and pass the serialized object in '@RequestBody' to your controller method
-
ci_ almost 9 yearsShow the exact exception/stack trace please.
-
Gregor almost 9 years@Darshan, the "headers" in RequestMapping does not change the behaviour. I update the question with a coding example.
-
-
Gregor almost 9 yearsI had used the consumes condition before. It was Darsham who recommended to use the accept header. But the consumes leads to the same problem.