Spring mvc 在springmvc@ResponseBody中返回文本JSON字符串
我将对象作为JSON字符串存储在数据库中。我想创建一个公开这些字符串的REST服务。然而,当我编写我的方法时,我得到的字符串将其引号转义。例如,我包含了一个返回字符串的方法Spring mvc 在springmvc@ResponseBody中返回文本JSON字符串,spring-mvc,jackson,Spring Mvc,Jackson,我将对象作为JSON字符串存储在数据库中。我想创建一个公开这些字符串的REST服务。然而,当我编写我的方法时,我得到的字符串将其引号转义。例如,我包含了一个返回字符串的方法 @RequestMapping(value = "test", method = RequestMethod.GET) public @ResponseBody String getTest() { return "{\"a\":1, \"b\":\"foo\"}"; } 但是当我在浏览器中调用这个方法时,我得到了
@RequestMapping(value = "test", method = RequestMethod.GET)
public @ResponseBody
String getTest() {
return "{\"a\":1, \"b\":\"foo\"}";
}
但是当我在浏览器中调用这个方法时,我得到了一个返回“{\'a\':1,\'b\':\'foo\'”}”,而我真正想要发生的是{“a”:1,b:'foo'}。我认为“String”作为返回类型可能是个问题,但是我还能做什么呢?包装器类执行相同的操作:
{
"value" : "{\"a\":1, \"b\":\"foo\"}"
}
我可以序列化它,然后返回对象,但这似乎有点荒谬。
以下是我的配置文件的相关部分:
@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;
}
这导致了一个尴尬的“价值”在前面,虽然这没有真正的意义
基本上,我想要的是@JsonRawValue,但是让它在RequestMapping方法而不是属性上工作。
思想?意见?其他建议?该\“
表示正在转义字符”
,这是标准的。如果是这样打印的,则可能是对对象进行了双重序列化。这适用于Jackson 2(至少):
不是特别漂亮,但很管用。我只希望Spring支持这一点:
@RequestMapping(..)
public @JsonRawValue @ResponseBody String get() {
// ...
}
我用了这个:
@RequestMapping(..)
@ResponseBody
public JsonNode myGetRequest(){
...
//rawJsonString is the raw Json that we want to proxy back to the client
return objectMapper.readTree(rawJsonString);
}
Jackson转换器知道如何将JsonNode转换为纯Json。我猜您想要的是生成一个内容类型为
application/Json
的响应。在您的情况下,当json数据作为原始字符串时,请执行以下操作:
在控制器中,将products=“application/json”
添加到@RequestMapping
属性:
@RequestMapping(value = "test", method = RequestMethod.GET, produces="application/json")
public @ResponseBody
String getTest() {
return "{\"a\":1, \"b\":\"foo\"}";
}
然后必须配置StringHttpMessageConverter
以接受应用程序/json媒体类型
使用Java配置:
@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);
}
@覆盖
公共无效配置MessageConverters(
List我知道这是一个老问题,但我自己正在处理相反的问题(我返回一个字符串并希望它转换为JSON)。在您的情况下,听起来您只是希望将字符串作为普通字符串处理,而不希望对其进行任何JSON转换,因为您已经有了JSON
因此,在您的情况下,您不想使用MappingJacksonHttpMessageConverter
(或者MappingJackson2HttpMessageConverter
,如果您现在使用的是Jackson2)。您根本不希望进行任何转换,该转换器将Java对象转换为JSON或从JSON转换为JSON。因此,您应该只使用普通的StringHttpMessageConverter
。您可以通过如下更改设置方法来实现此目的:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter());
}
@覆盖
public void configureMessageConverters(List在我的例子中,我希望响应类型由请求参数确定,因此必须在代码中指定内容类型,例如:
@RequestMapping("/myurl")
public void radiusSearch(@RequestParam responseType, HttpServletResponse response) throws IOException {
String jsonResponse = makeSomeJson();
response.setContentType(responseType);
try {
response.getOutputStream().write(jsonResponse.getBytes());
} finally {
response.getOutputStream().close();
}
}
今天,我们遇到了同样的问题,并用多个转换器解决了它。现在每个字符串
都将被视为字符串,其他每个对象
都将由Jackson序列化。这允许在Spring控制器中手动(通过返回字符串
)或自动(通过返回其他内容)序列化
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(stringConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
@Bean
public StringHttpMessageConverter stringConverter() {
final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(UTF_8);
stringConverter.setSupportedMediaTypes(Arrays.asList(
MediaType.TEXT_PLAIN,
MediaType.TEXT_HTML,
MediaType.APPLICATION_JSON));
return stringConverter;
}
@Bean
public GenericHttpMessageConverter<Object> mappingJackson2HttpMessageConverter() {
final ObjectMapper objectMapper = objectMapperBuilder().build();
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
return converter;
}
@覆盖
public void configureMessageConverters(列表如果要在浏览器中将JSON字符串转换为JSON对象,请在Jackson Converter之前保留字符串转换器。
下面是一个完整的例子。它与自定义转换器配置和弹簧验证一起使用
它起作用了
没有
您的问题的解决方案是,这在不改变任何配置的情况下都能完美工作
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
JsonNode getTest() {
return JsonLoader.fromString("{\"a\":1, \"b\":\"foo\"}");
}
是的,双重序列化可以解释这个问题。但是在哪里?看起来你解析了rawJsonString,然后返回了将再次转换为json的对象。这不是一个很好的解决方案……非常感谢,这确实帮助我避免了返回带有转义符的JsonObject!帮了大忙。在过去3年中有什么变化吗?@Kulpemovitz,我不知道在是我的问题。将插入顺序更改为列表解决了问题。+1此问题应标记为正确的解决方案:-)谢谢
@RequestMapping("/myurl")
public void radiusSearch(@RequestParam responseType, HttpServletResponse response) throws IOException {
String jsonResponse = makeSomeJson();
response.setContentType(responseType);
try {
response.getOutputStream().write(jsonResponse.getBytes());
} finally {
response.getOutputStream().close();
}
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(stringConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
@Bean
public StringHttpMessageConverter stringConverter() {
final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(UTF_8);
stringConverter.setSupportedMediaTypes(Arrays.asList(
MediaType.TEXT_PLAIN,
MediaType.TEXT_HTML,
MediaType.APPLICATION_JSON));
return stringConverter;
}
@Bean
public GenericHttpMessageConverter<Object> mappingJackson2HttpMessageConverter() {
final ObjectMapper objectMapper = objectMapperBuilder().build();
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
return converter;
}
converters.add(stringConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
converters.add(mappingJackson2HttpMessageConverter());
converters.add(stringConverter());
super.configureMessageConverters(converters);
import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
JsonNode getTest() {
return JsonLoader.fromString("{\"a\":1, \"b\":\"foo\"}");
}