Reputation: 2599
I am returning a string object from spring controller like
@RequestMapping(value = "/persons.html", method = RequestMethod.GET)
public @ResponseBody String listPersonHtml(Model model) {
return "{\"abc\":\"test\"}";
}
I am getting response on ui like "{\"abc\":\"test\"}",i want this response as
{"abc":"test"}
i.e pure json object.
what type of configuration I need?
On UI side,if I set Accept */*
then I face this issue,if I set Accept text/html
or Accept text/plain
then no issue is there,but I can't change accept header.
Upvotes: 1
Views: 1243
Reputation: 11
Old question, but I just had to solve the same issue and most of the answers I found resulted misleading, so here's mine:
It all starts with the Controller, and Spring trying to answer a mapped request in the format that the invoking client is expecting. The client can inform this using different HTTP features, and there is where the different HttpMessageConverter implementations are involved. Spring pick's the format to answer based on different strategies, applied by the ContentNegotiationManager.
By prioritizing StringHttpMessageConverter over MappingJackson2XmlHttpMessageConverter you are only telling Spring to answer in "text/plain" format over "application/json", and it will work until a client specifies that is expecting a json response (this is mostly done by setting the Accept header in the request, although there are other ways to do it). The important thing is that if a client sets that header to "application/json", Spring will use MappingJackson2XmlHttpMessageConverter that will translate the Java String to a Json String, ending up with something like "{\"abc\":\"test\"}" instead of {"abc":"test"}
So, the real issue that every developer faces in this case is that MappingJackson2XmlHttpMessageConverter translates a Java String to a Json String, and in some cases, you might not need that, because the string contains valid json that needs to be returned without modifications. There are some configuration classes for this MessageConverter but I did'n went that road, because I need to return Strings like "raw" Json only in some specific endpoints (performance is the key driver). Here's an expample that resumes my "approach":
@RestController
@RequestMapping(value = "test", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class TestController {
@RequestMapping(method = RequestMethod.GET, value = "endpoint")
public JsonObject getSomeJson() {
return new JsonObject("{\"abc\":\"test\"}");
}
private static class JsonObject {
private String rawJsonValue;
JsonObject(String rawJsonValue) {
this.rawJsonValue = rawJsonValue;
}
@JsonValue @JsonRawValue
public String getRawJsonValue() {
return rawJsonValue;
}
}
}
@JsonValue and @JsonRawValue are Jackson annotations that tell MappingJackson2XmlHttpMessageConverter to treat the getRawJsonValue method result as the Json representation of JsonObject, without making any modification. The response of the endpoint will be {"abc":"test"}
Upvotes: 1
Reputation: 2599
I found the way.Its all about spring message-converters.I added MappingJackson2HttpMessageConverter in this list and this converter tries to convert string to json and produces this result. Just add org.springframework.http.converter.StringHttpMessageConverter before MappingJackson2HttpMessageConverter so that StringHttpMessageConverter can come into action and string can be returned as it is.
Upvotes: 2