Spring MVC @ResponseBodyでリテラルJSON文字列を返す 質問する

Spring MVC @ResponseBodyでリテラルJSON文字列を返す 質問する

私はデータベースにオブジェクトをJSON文字列として保存しています。これらの文字列を公開するRESTサービスを作りたいのですが、メソッドを書くと、返される文字列の引用符がエスケープされます。たとえば、Stringを返すメソッドを含めました。

@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;
}

ありがとう

編集: 以下に示唆されているように、文字列が二重にエンコードされているようです。構成内の 2 つのクラスをコメント アウトすると、この問題は修正されます。ただし、オブジェクトを返す必要がある場所がまだ他にもあるため、構成場所がわかっている共通のシリアル化 Bean を通じてそれらのオブジェクトを実行し続けたいと考えています。そのため、次のようなオプションがあります。a) すべてのシリアル化を自分で行う。すべてのメソッドは文字列を返し、すでに JSON になっているメソッドはそれ自体を返し、オブジェクトであるメソッドはすべて JSONUtil.toJson(object) を返します。このアプローチは好きではありませんが、機能することはわかっています。b) 次のようなラッパー クラスを使用する:

public static class Wrapper {

    @JsonRawValue
    private final String value;
}

これにより、実際には意味のない、扱いにくい「値」が先頭に現れます。

基本的に私が欲しいのは @JsonRawValue ですが、プロパティではなく RequestMapping メソッドで動作するようにしたいです。ご意見、ご意見、その他の提案はありますか?

ベストアンサー1

これは 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;
    }
}

特にきれいではありませんが、動作します。Spring がこれをサポートしてくれるといいのですが:

@RequestMapping(..)
public @JsonRawValue @ResponseBody String get() {
    // ...
}

おすすめ記事