加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 同一返回类型的多个Jackson序列化程序

发布时间:2020-12-15 04:15:24 所属栏目:Java 来源:网络整理
导读:我正在使用Jackson进行 JSON序列化,并编写了一些自定义String序列化程序,一个用于类的每个getter方法.每个方法返回相同的类型,Set String,但每个都使用不同的序列化程序. 不幸的是,杰克逊没有使用每个序列化器,每个方法一个,但是两个都使用一个序列化器.它似
我正在使用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;
  }
}

有关如何使用FooSerializer获取getFoos()方法序列化以及使用BarSerializer序列化的getBars()方法的任何建议?在此示例中,将为两种方法调用BarSerializer.

注意,如果我将其中一个方法的签名更改为另一个集合类型,那么它们就不同了 – List< String>例如 – 序列化工作.

提前致谢.

解决方法

我认为当将ObjectMapper与@JsonSerialize(contentUsing = BarSerializer.class)结合使用时,您在1.9.xx版本中无法实现的目标.

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

虽然BeanProperty传递给此方法,但它不会用作缓存键的一部分.您可以继承StdSerializerProvider并在缓存值序列化器时考虑BeanProperty参数,但这可能不是解决问题的最简单方法.

快速解决方法是使用@JsonSerialize(使用= FooCollectionSerializer.class)并自行处理序列化.通过执行此操作,序列化程序是用于序列化属性的BeanPropertyWriter的directly coupled.使用@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,SerializerProvider provider) throws IOException {
            jgen.writeString(value);
        }
    }

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

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

            }
            jgen.writeEndArray();
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读