Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 相同返回类型的多个Jackson序列化程序_Java_Json_Jackson - Fatal编程技术网

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

Java 相同返回类型的多个Jackson序列化程序,java,json,jackson,Java,Json,Jackson,我使用Jackson进行JSON序列化,并编写了两个自定义的String序列化程序,一个类的每个getter方法都有一个序列化程序。每个方法都返回相同的类型,Set,但每个方法使用不同的序列化程序 不幸的是,Jackson并没有使用每个序列化程序,每个方法使用一个序列化程序,而是两个方法都使用一个序列化程序。它似乎接受按字母顺序排在第一位的任何方法,并对这两个方法使用其序列化程序。我期望第一个方法上注释的序列化程序用于第一个方法,第二个方法上注释的序列化程序用于第二个方法。调试似乎表明Jacks

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

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

例如:

公共类FooBar{
私有集foos=newhashset();
private Set bar=new HashSet();
@JsonProperty(“FooWrapper”)
@JsonSerialize(contentUsing=FooSerializer.class)
公共集getFoos(){
返回foos;
}
@JsonProperty(“BarWrapper”)
@JsonSerialize(contentUsing=BarSerializer.class)
公共设置getbar(){
返回杆;
}
}
关于如何让
getFoos()
方法使用
FooSerializer
进行序列化,以及如何让
getbar()
方法使用
BarSerializer
进行序列化,有何建议?在本例中,这两种方法都调用了
BarSerializer

注意,如果我将其中一个方法的签名更改为另一个集合类型,使它们不同-
List
,例如,序列化可以工作


提前感谢。

我认为在1.9.xx版中,如果将
对象映射器
@JsonSerialize(contentUsing=BarSerializer.class)
结合使用,您想要实现的目标是不可能的

Jackson确实缓存了序列化程序,它基于与序列化程序关联的
JavaType
(在本例中为
Set
)缓存它们。看

虽然
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();
        }
    }
}
公共类FooBar{
私有集foos=newhashset();
private Set bar=new HashSet();
@JsonProperty(“FooWrapper”)
@JsonSerialize(使用=FooCollectionSerializer.class)
公共集getFoos(){
返回foos;
}
@JsonProperty(“BarWrapper”)
@JsonSerialize(使用=BarCollectionSerializer.class)
公共设置getbar(){
返回杆;
}
公共静态类FooCollectionSerializer扩展了JsonSerializer{
JsonSerializer序列化程序;
公共食品收集序列化程序(){
//让Jackson处理序列化集合的问题,只需指定序列化单个项的方式
this.serializer=new StringCollectionSerializer(null,new FooSerializer());
}
@凌驾
public void serialize(集合值、JsonGenerator jgen、SerializerProvider提供程序)引发IOException、JsonProcessingException{
serializer.serialize(值、jgen、提供程序);
}
}
公共静态类FooSerializer扩展SerializerBase{
公共序列化程序(){
super(String.class);
}
@凌驾
公共void序列化(字符串值、JsonGenerator jgen、SerializerProvider提供程序)引发IOException{
jgen.writeString(值);
}
}
公共静态类BarCollectionSerializer扩展了JsonSerializer{
@凌驾
public void serialize(集合值、JsonGenerator jgen、SerializerProvider提供程序)引发IOException、JsonProcessingException{
//自己处理序列化集合
jgen.writestarray();
for(字符串值:值){
jgen.writeString(值);
}
jgen.writeEndArray();
}
}
}

我们可以知道您正在使用的Jackson版本吗?我已经在Jackson(org.codehaus.Jackson)1.9.11中检查过这种行为,但它不起作用。在此之后,我将Jackson库更新为2.2.2版(com.fasterxml.Jackson),效果非常好。你能在你的项目中升级Jackson库吗?我想我不能,因为另一个使用Jackson的工具我最终升级到了Jackson 2.x,一切都很好。谢谢。我最终升级到了Jackson 2,这需要我将另一个工具(Spring Integration)升级到一个非官方版本,但一切正常。我奖励你一笔赏金,因为你提供了一个获得杰克逊的详细例子
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();
        }
    }
}