@RequestBody gives empty JsonObject when making a POST Request
The explanation why it fails is perfectly done at Sotirios Delimanolis answer.
However there is a workaround:
@RequestBody Map<String, String> json
That way you can continue using Jackson HttpMessageConverter and work with custom objects in payload.
It is quite simple
@PostMapping
public ResponseEntity<?> yourMethod(@RequestBody String data) {
JSONObject jsonObject = new JSONObject(data);
//use the jsonObject now
}
Spring no longer supports Jackson 1 as a message converter implementation.
So your
compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
is actually meaningless to Spring.
Your
compile 'com.google.code.gson:gson:2.3.1'
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
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"}
Since you're saying that you're getting an empty JsonObject
, I can only assume that you have Jackson 2 on your classpath.
Spring registers the Jackson HttpMessageConverter
, MappingJackson2HttpMessageConverter
, before the GsonHttpMessageConverter
if both are present on the classpath.
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);
which you'll note results in
{}
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.
One solution is to remove Jackson 2 from the classpath. Another solution is to explicitly add HttpMessageConverter
instances in the order you want.