0

以下の単体テストには、beanA と beanB の 2 つの Bean があり、beanA には beanB への参照が含まれています。

JSON ビューを提供する Bean をカスタムシリアライザーでシリアライズする場合、beanB のカスタム シリアライザーは提供された JSON ビューを認識しません。テストの出力は次のとおりです。

{
  "clazz" : "BeanA",
  "activeView" : "ViewTest",
  "beanB" : {
    "clazz" : "BeanB",
    "activeView" : null
  }
}

activeView を伝播するために私が見つけた唯一の方法は次のとおりです: (以下の完全なソースコードを参照)

ObjectMapper mapper = (ObjectMapper) gen.getCodec();
mapper.setConfig(provider.getConfig());

しかし、setConfig() の JavaDoc には、「自分が何をしているのかわかっている場合にのみ、このメソッドを使用してください」と書かれています。

だから私の質問は:

  1. JSON ビューを伝播するこの方法は問題ありませんか?
  2. より良い方法はありますか?
  3. 誰かがデフォルトの動作を説明できますか?

(***でマークされたコメントアウトされた行があります-これらは、カスタムシリアライザーなしで遊んでいる場合にのみ興味深いものです(その場合、JSONビューが伝播されるようです))

public class ViewTest {

    @Test
    public void hello() throws JsonProcessingException {

        BeanA beanA = new BeanA();
        beanA.beanB = new BeanB();

        String result = new ObjectMapper()
//            .disable(MapperFeature.DEFAULT_VIEW_INCLUSION) // ***
            .writerWithView(ViewTest.class)
            .withDefaultPrettyPrinter()
            .writeValueAsString(beanA);

        System.out.println(result);
    }

    @JsonSerialize(using = BeanASerializer.class)
    static public class BeanA {

//        @JsonView(ViewTest.class) // ***
        public String clazz = this.getClass().getSimpleName();

//        @JsonView(ViewTest.class) // ***
        public BeanB beanB;
    }

    @JsonSerialize(using = BeanBSerializer.class)
    static public class BeanB {

//        @JsonView(ViewTest.class) // ***
        public String clazz = this.getClass().getSimpleName();
    }

    static void writeClazzAndActiveView(String clazz, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStringField("clazz", clazz);
        gen.writeFieldName("activeView");
        if (provider.getActiveView() == null) {
            gen.writeNull();
        } else {
            gen.writeString(provider.getActiveView().getSimpleName());
        }
    }

    static class BeanASerializer extends JsonSerializer<BeanA> {

        @Override
        public void serialize(BeanA bean, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {

            gen.writeStartObject();
            writeClazzAndActiveView(bean.clazz, gen, provider);

            // the only way I found to propagate the activeView:
//            ObjectMapper mapper = (ObjectMapper) gen.getCodec();
//            mapper.setConfig(provider.getConfig());

            gen.writeObjectField("beanB", bean.beanB);
            gen.writeEndObject();
        }
    }

    static class BeanBSerializer extends JsonSerializer<BeanB> {

        @Override
        public void serialize(BeanB bean, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {

            gen.writeStartObject();
            writeClazzAndActiveView(bean.clazz, gen, provider);
            gen.writeEndObject();
        }
    }
}
4

1 に答える 1