gpt4 book ai didi

java - Jackson @JsonUnwrapped 行为与自定义 JsonSerializer

转载 作者:搜寻专家 更新时间:2023-10-31 19:27:30 31 4
gpt4 key购买 nike

我有两个这样的类:

public class A {
String aProp = "aProp";

public String getAProp() {
return aProp;
}
}

public class B {
String bProp = "bProp";
A a = new A();

@JsonProperty("bProp")
public String getBProp() {
return bProp;
}

@JsonSerialize(using = CustomSerializer.class)
public A getA() {
return a;
}
}

我希望得到这样的 JSON:

{
"bProp": "bProp", // just serizlised bProp
"sProp1": "sProp1_aProp", // computed using aProp
"sProp2": "sProp2_aProp" // computed another way
}

所以我像这样编写了自定义 JsonSerializer:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class CustomSerializer extends JsonSerializer<A> {
@Override
public void serialize(A a, JsonGenerator json, SerializerProvider provider) throws IOException {
json.writeStringField("sProp1", "sProp1_" + a.getAProp());
json.writeStringField("sProp2", "sProp2_" + a.getAProp());
}
}

但我一直收到错误:

com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value

除非我将 json.writeStartObject();json.writeEndObject(); 放在序列化方法中(因此它会产生错误的 JSON)。

所以我正在寻找像 @JsonUnwrapped 这样的解决方案来与自定义 JsonSerializer 一起使用。

最佳答案

我了解您的问题,您需要的是 UnwrappingBeanSerializer。你可以看到另一个相关的 SO 帖子: Different JSON output when using custom json serializer in Spring Data Rest

问题是你不能在一个字段中同时使用注释 @JacksonUnwrapped@JsonSerialize 因为当你使用 @JsonSerializer 时,Jackson 将始终写字段名。

这里是完整的解决方案:

public class CustomSerializer  extends UnwrappingBeanSerializer {
public CustomSerializer(BeanSerializerBase src, NameTransformer transformer) {
super(src, transformer);
}

@Override
public JsonSerializer<Object> unwrappingSerializer(NameTransformer transformer) {
return new CustomSerializer(this, transformer);
}

@Override
protected void serializeFields(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
A a = (A) bean;
jgen.writeStringField("custom", a.getAProp());
jgen.writeStringField("custom3", a.getAProp());
}

@Override
public boolean isUnwrappingSerializer() {
return true;
}

}

测试用例,您应该使用自定义配置或研究其他方法重新定义您的对象映射器。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = Application.class)
public class ColorsTest {

ObjectMapper mapper = new ObjectMapper();

@Before
public void setUp(){
mapper.registerModule(new Module() {
@Override
public String getModuleName() {
return "my.module";
}

@Override
public Version version() {
return Version.unknownVersion();
}

@Override
public void setupModule(SetupContext context) {

context.addBeanSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if(beanDesc.getBeanClass().equals(A.class)) {
return new CustomSerializer((BeanSerializerBase) serializer, NameTransformer.NOP);
}
return serializer;
}
});

}
});
}
@Test
public void testSerializer() throws JsonProcessingException {
System.out.println(mapper.writeValueAsString(new B()));
}
}

B 类:

public class B {

@JsonProperty("bProp")
public String getBProp() {
return "bProp";
}


@JsonUnwrapped
public A getA() {
return new A();
}
}

关于java - Jackson @JsonUnwrapped 行为与自定义 JsonSerializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30846404/

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