以下の単体テストには、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 には、「自分が何をしているのかわかっている場合にのみ、このメソッドを使用してください」と書かれています。
だから私の質問は:
- JSON ビューを伝播するこの方法は問題ありませんか?
- より良い方法はありますか?
- 誰かがデフォルトの動作を説明できますか?
(***でマークされたコメントアウトされた行があります-これらは、カスタムシリアライザーなしで遊んでいる場合にのみ興味深いものです(その場合、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();
}
}
}