我正在使用Jackson进行JSON序列化,并编写了一些自定义String序列化程序,一个用于类的每个getter方法.每个方法都返回相同的类型Set<String>,但每个方法使用不同的序列化程序.
不幸的是,杰克逊没有使用每个序列化器,每个方法一个,但是两个都使用一个序列化器.它似乎采用按字母顺序排列的任何方法,并将两种方法用于序列化程序.我期望的是第一种方法注释的序列化器用于第一种方法,第二种方法注释的序列化器用于第二种方法.调试似乎表明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;
}
}
Run Code Online (Sandbox Code Playgroud)
有关如何getFoos()使用a 获取方法序列化的任何建议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)和处理自己序列化集合.通过这样做,序列化器直接耦合到BeanPropertyWriter用于序列化属性.当使用时@JsonSerialize(contentUsing = BarSerializer.class),没有串行器耦合到BeanPropertyWriter哪个序列化器触发串行器查找,该序列化器查找基于序列化器缓存序列化器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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3049 次 |
| 最近记录: |