文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

Spring bootでjsonpの先頭に謎の/**/が混入する問題とその対応:その2

今度はObjectMapperの設定と組み合わせた場合の例ですよ〜
f:id:treeapps:20180802010416p:plain

www.bunkei-programmer.net
前回の記事でjsonp出力時に謎のコメントが混入する件の解決方法を書きました。しかし前回はObjectMapperにインデントの設定をしたり、null値の属性出力の抑制等の設定をしていなかったため、あまり実践的なコードではありませんでした。

今回はjacksonのObjectMapperに各種設定をしつつ謎のコメントが入らないようにする設定についてまとめます。

環境

  • JDK1.8
  • Spring boot 1.3.2.RELEASE

☓ 駄目な例

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true).serializationInclusion(JsonInclude.Include.NON_NULL);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}

これは駄目でした。インデントが有効になってnull値の場合に属性が出力されないようになったのですが、以下のように謎の「/**/」が混入してしまいます。

/**/test({
  "head" : {
    "code" : 200
  },
  "body" : {
    "cd" : "コードです",
    "name" : "名前です"
  }
});

◯ 正しい例

@Configuration
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true).serializationInclusion(JsonInclude.Include.NON_NULL);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()) {

            @Override
            protected void writePrefix(JsonGenerator generator, Object obj) throws IOException {
                if (!(obj instanceof MappingJacksonValue))
                    return;
                String funcName = ((MappingJacksonValue) obj).getJsonpFunction();
                if (funcName != null)
                    generator.writeRaw(funcName + "(");
            }
        });
    }
}

答えは簡単でした。前回の記事と今回のJackson2ObjectMapperBuilderを組み合わせるだけです。これで以下のように先頭の謎のコメントは削除されます。

test({
  "head" : {
    "code" : 200
  },
  "body" : {
    "cd" : "コードです",
    "name" : "名前です"
  }
});