I am storing objects in my database as JSON strings. I want to make a REST service that exposes these strings. When I write my methods however, the strings I get back have their quotes escaped. For example, I have included a method that returns a String,
@RequestMapping(value = "test", method = RequestMethod.GET) public @ResponseBody String getTest() { return "{\"a\":1, \"b\":\"foo\"}"; }
but when I call this method in the browser I get a back "{\"a\":1, \"b\":\"foo\"}" when what I really want to happen is {"a": 1, "b": "foo"}. I think "String" as the return type is likely the problem, but what else can I do? A wrapper class does the same thing:
{ "value" : "{\"a\":1, \"b\":\"foo\"}" }
I could serialize it and then return the object, but that seems a bit ridiculous. Here is a possibly the relevant portion of my configuration file:
@Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { super.configureMessageConverters(converters); converters.add(mappingJacksonHttpMessageConverter()); } @Bean MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter() { MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter = new MappingJacksonHttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); mappingJacksonHttpMessageConverter.setObjectMapper(objectMapper); mappingJacksonHttpMessageConverter.setPrettyPrint(true); return mappingJacksonHttpMessageConverter; }
Thanks
EDIT: as was suggested below, it seems the string is being double encoded. Commenting out the 2 classes in my configuration fixes this issue. However, I still have other places where I want to return Objects and would like to keep those running through that common serializing bean that I know where to configure. So I see my options as: a) Do all the serializing myself. All methods return Strings, and those that are already JSON return themselves, and those that are objects all return JSONUtil.toJson(object). I don't love this approach, but I know it will work. b) Use a wrapper class that looks kind of like:
public static class Wrapper { @JsonRawValue private final String value; }
This leads to an awkward "value" at the front though that has no real meaning.
Basically what I want is @JsonRawValue, but to have it work on RequestMapping methods instead of properties. Thoughts? Opinions? Other suggestions?
This works with Jackson 2 (at least):
@Controller public class YourController { @RequestMapping(..) public @ResponseBody Json get() { return new Json("{ \"attr\" : \"value\" }"); } } class Json { private final String value; public Json(String value) { this.value = value; } @JsonValue @JsonRawValue public String value() { return value; } }
Not particularly pretty but works. I only wish Spring supported this:
@RequestMapping(..) public @JsonRawValue @ResponseBody String get() { // ... }
I guess what you want is producing a response with content-type application/json
. In your case, when you have the json-data as a raw string, do the following:
In your controller add produces="application/json"
to your @RequestMapping
attribute:
@RequestMapping(value = "test", method = RequestMethod.GET, produces="application/json") public @ResponseBody String getTest() { return "{\"a\":1, \"b\":\"foo\"}"; }
Then you have to configure the StringHttpMessageConverter
to accept the application/json media-type.
With Java-config:
@Override public void configureMessageConverters( List<HttpMessageConverter<?>> converters) { StringHttpMessageConverter stringConverter = new StringHttpMessageConverter( Charset.forName("UTF-8")); stringConverter.setSupportedMediaTypes(Arrays.asList( // MediaType.TEXT_PLAIN, // MediaType.TEXT_HTML, // MediaType.APPLICATION_JSON)); converters.add(stringConverter); }
With XML-config:
<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <array> <bean class = "org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json; charset=UTF-8" /> </bean> </array> </property> </bean>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With