gpt4 book ai didi

java - @JsonView 未传播到 ("nested")自定义序列化器

转载 作者:行者123 更新时间:2023-12-02 10:33:11 24 4
gpt4 key购买 nike

在下面的单元测试中,有两个 bean:beanA 和 beanB,其中 beanA 包含对 beanB 的引用。

当使用自定义序列化器序列化提供 JSON View 的 beans 时,beanB 的自定义序列化器不知道提供的 JSON View ,因为测试的输出是:

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

我发现传播 activeView 的唯一方法是:(请参阅下面的完整源代码)

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

但是 setConfig() 的 JavaDoc 说“只有当你知道自己在做什么时才使用这个方法”——我显然不会这样做......

所以我的问题是:

  1. 这种传播 JSON View 的方式可以吗?
  2. 有更好的方法吗?
  3. 有人可以解释一下默认行为吗?

(有一些行被注释掉了 *** - 这些只有在没有自定义序列化器的情况下才有意义(在这种情况下,JSON View 似乎会被传播))

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();
}
}
}

最佳答案

Active 应通过 SerializerProvider 正确传播。你是对的,你不应该以这种方式设置(也不必设置) View - 首先,它不是线程安全的,并且 ObjectMapper 的所有配置都应在任何和所有之前完成使用(ObjectReaderObjectWriter 允许通过各种工厂方法进行每次调用更改)。

为什么会发生这种情况尚不清楚:我认为使用版本信息和完整复制(如果除了代码之外还有更多内容)提交错误是有意义的。

关于java - @JsonView 未传播到 ("nested")自定义序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53484875/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com