gpt4 book ai didi

java - 相同返回类型的多个 Jackson 序列化程序

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:27:32 26 4
gpt4 key购买 nike

我正在使用 Jackson 进行 JSON 序列化并编写了一些自定义 String序列化器,一个类的每个 getter 方法。每个方法都返回相同的类型,Set<String> ,但每个都使用不同的序列化器。

不幸的是,Jackson 没有使用每个序列化器,每个方法一个,而是为两种方法使用一个序列化器。它似乎采用按字母顺序排在第一位的任何方法,并为这两种方法使用其序列化程序。我期望的是第一个方法上注释的序列化器用于第一个方法,第二个方法上注释的序列化器用于第二个方法。调试似乎表明 Jackson 在映射中有序列化程序,该映射由方法的返回类型键入(两者都相同)。

一个例子:

public class FooBar {

private Set<String> foos = new HashSet<String>();
private Set<String> bars = new HashSet<String>();

@JsonProperty("FooWrapper")
@JsonSerialize(contentUsing = FooSerializer.class)
public Set<String> getFoos() {
return foos;
}

@JsonProperty("BarWrapper")
@JsonSerialize(contentUsing = BarSerializer.class)
public Set<String> getBars() {
return bars;
}
}

关于如何获得 getFoos() 的任何建议用 FooSerializer 序列化的方法, 和 getBars()使用 BarSerializer 序列化的方法?在此示例中,BarSerializer为这两种方法调用。

请注意,如果我将其中一种方法的签名更改为另一种集合类型,那么它们就会不同 - List<String>例如 - 序列化有效。

提前致谢。

最佳答案

我认为当使用 ObjectMapper 时,您想要实现的目标在 1.9.xx 版中是不可能的。结合 @JsonSerialize(contentUsing = BarSerializer.class) .

Jackson 确实缓存了序列化程序,它根据 JavaType 缓存它们。 (在本例中为 Set<String> ) 与序列化程序相关联。参见 StdSerializerProvider.findValueSerializer(JavaType valueType, BeanProperty property) .

尽管 BeanProperty传递给此方法,它不用作缓存键的一部分。你可以继承 StdSerializerProvider并采取 BeanProperty缓存值序列化程序时考虑参数,但这可能不是解决问题的最简单方法。

快速解决方法是使用 @JsonSerialize(using = FooCollectionSerializer.class)并自己处理系列化。通过这样做,序列化器是 directly coupledBeanPropertyWriter用于序列化属性。使用 @JsonSerialize(contentUsing = BarSerializer.class)BeanPropertyWriter 没有耦合序列化器这会触发 serializer lookup缓存基于 JavaType 的序列化程序

public class FooBar {

private Set<String> foos = new HashSet<>();
private Set<String> bars = new HashSet<>();

@JsonProperty("FooWrapper")
@JsonSerialize(using = FooCollectionSerializer.class)
public Set<String> getFoos() {
return foos;
}

@JsonProperty("BarWrapper")
@JsonSerialize(using = BarCollectionSerializer.class)
public Set<String> getBars() {
return bars;
}

public static class FooCollectionSerializer extends JsonSerializer<Collection<String>> {

JsonSerializer<Collection<String>> serializer;

public FooCollectionSerializer() {
//let Jackson deal with serializing the collection and just specify how you want to serialize indivial items
this.serializer = new StringCollectionSerializer(null, new FooSerializer());
}

@Override
public void serialize(Collection<String> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
serializer.serialize(value, jgen, provider);
}
}

public static class FooSerializer extends SerializerBase<String> {
public FooSerializer() {
super(String.class);
}

@Override
public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeString(value);
}
}

public static class BarCollectionSerializer extends JsonSerializer<Collection<String>> {

@Override
public void serialize(Collection<String> values, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
//handle serializing the collection yourself
jgen.writeStartArray();
for (String value : values) {
jgen.writeString(value);

}
jgen.writeEndArray();
}
}
}

关于java - 相同返回类型的多个 Jackson 序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20037695/

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