在spring mvc @ResponseBody中返回文字JSON字符串

new*_*nne 29 spring-mvc jackson

我将对象作为JSON字符串存储在我的数据库中.我想制作一个暴露这些字符串的REST服务.然而,当我编写我的方法时,我回来的字符串会引用它们的引号.例如,我已经包含了一个返回String的方法,

@RequestMapping(value = "test", method = RequestMethod.GET)
public @ResponseBody
String getTest() {
    return "{\"a\":1, \"b\":\"foo\"}";
}
Run Code Online (Sandbox Code Playgroud)

但是当我在浏览器中调用此方法时,我得到一个"{\"a \":1,\"b \":\"foo \"}"当我真正想要发生的是{"a":1 ,"b":"foo"}.我认为"String"作为返回类型可能是问题所在,但我还能做些什么呢?包装器类做同样的事情:

{
  "value" : "{\"a\":1, \"b\":\"foo\"}"
}
Run Code Online (Sandbox Code Playgroud)

我可以序列化然后返回对象,但这看起来有点荒谬.这可能是我的配置文件的相关部分:

@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;
}
Run Code Online (Sandbox Code Playgroud)

谢谢

编辑:如下所示,似乎字符串是双重编码.在我的配置中注释掉这两个类可以解决这个问题.但是,我仍然有其他地方我想要返回对象,并希望保持那些运行通过我知道在哪里配置的常见序列化bean.所以我认为我的选择是:a)自己做所有的序列化.所有方法都返回Strings,那些已经是JSON的方法返回自己,而那些作为对象的方法都返回JSONUtil.toJson(object).我不喜欢这种方法,但我知道它会起作用.b)使用类似于以下内容的包装类:

public static class Wrapper {

    @JsonRawValue
    private final String value;
}
Run Code Online (Sandbox Code Playgroud)

这导致前面的尴尬"价值"虽然没有实际意义.

基本上我想要的是@JsonRawValue,但让它在RequestMapping方法而不是属性上工作.思考?意见?其他建议?

Juk*_*kka 43

这适用于Jackson 2(至少):

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

不是特别漂亮,但有效.我只希望Spring支持这个:

@RequestMapping(..)
public @JsonRawValue @ResponseBody String get() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

HTH,Jukka

  • 很好的帮助.过去3年有什么变化吗? (2认同)

Flo*_*ser 26

我想你想要的是产生一个内容类型的响应application/json.在您的情况下,当您将json数据作为原始字符串时,请执行以下操作:

在您的控制器中添加produces="application/json"您的@RequestMapping属性:

@RequestMapping(value = "test", method = RequestMethod.GET, produces="application/json")
public @ResponseBody
String getTest() {
    return "{\"a\":1, \"b\":\"foo\"}";
}
Run Code Online (Sandbox Code Playgroud)

然后你必须配置StringHttpMessageConverter接受application/json媒体类型.

使用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);
}
Run Code Online (Sandbox Code Playgroud)

使用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>
Run Code Online (Sandbox Code Playgroud)


小智 11

我用过这个:

@RequestMapping(..)
@ResponseBody
public JsonNode myGetRequest(){
...
//rawJsonString is the raw Json that we want to proxy back to the client
return objectMapper.readTree(rawJsonString);
}
Run Code Online (Sandbox Code Playgroud)

杰克逊转换器知道如何将JsonNode转换为普通的Json.


She*_*hid 5

如果要在浏览器中将JSON字符串转换为JSON对象,请在杰克逊转换器之前保留字符串转换器。
请点击此链接以获取完整示例。它与自定义转换器配置以及弹簧验证一起使用。

有用

converters.add(stringConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
Run Code Online (Sandbox Code Playgroud)

不会

converters.add(mappingJackson2HttpMessageConverter());
converters.add(stringConverter());
super.configureMessageConverters(converters);
Run Code Online (Sandbox Code Playgroud)


fcm*_*fcm 1

\"意味着字符"正在被转义,这是标准的。如果像这样打印,您可能正在双重序列化该对象。