Java – multiple Jackson serializers of the same return type

I'm using Jackson for JSON serialization and have written some custom string serializers, one for each getter method of the class Each method returns the same type, set < string >, but each uses a different serializer

Unfortunately, Jackson didn't use every serializer, one per method, but both used one serializer It seems to take any method in alphabetical order and uses its serializer for both methods What I expect is that the serializer of the first method annotation is used for the first method and the serializer of the second method annotation is used for the second method Debugging seems to indicate that Jackson typed the serializer in the map using the return type of the method (both are the same)

An example:

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

Any suggestions on how to get the getfoos () method serialization using fooserializer and the getbars () method serialization using barserializer? In this example, barserializer. Is called for both methods

Note that if I change the signature of one of the methods to another collection type, they are different - list < string > for example - serialization work

Thank you in advance

Solution

I think when using objectmapper with @ jsonserialize (contentusing = barserializer. Class), you are in 1.9 Goals that cannot be achieved in XX version

Jackson does cache serializers and caches them according to the javatype associated with the serializer (in this case, set < string >) See stdserializerprovider findValueSerializer(JavaType valueType,BeanProperty property).

Although beanproperty is passed to this method, it will not be used as part of the cache key You can inherit stdserializerprovider and consider the beanproperty parameter when caching the value serializer, but this may not be the easiest way to solve the problem

A quick fix is to use @ jsonserialize (use = foocollectionserializer. Class) and handle serialization yourself By doing this, the serializer is the directly coupled. Serializer of the beanpropertywriter used to serialize properties When @ jsonserialize (contentusing = barserializer. Class) is used, no serializer coupled with beanpropertywriter triggers serializer lookup to cache the serializer according to 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();
        }
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>