Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc 在springmvc@ResponseBody中返回文本JSON字符串_Spring Mvc_Jackson - Fatal编程技术网

Spring mvc 在springmvc@ResponseBody中返回文本JSON字符串

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\"}"; } 但是当我在浏览器中调用这个方法时,我得到了

我将对象作为JSON字符串存储在数据库中。我想创建一个公开这些字符串的REST服务。然而,当我编写我的方法时,我得到的字符串将其引号转义。例如,我包含了一个返回字符串的方法

@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\"}");
}