Gson忽略序列化排除策略

kyks70gy  于 2022-11-06  发布在  其他
关注(0)|答案(2)|浏览(208)

正在序列化

public class Subclass extends Superclass {
    private static final long serialVersionUID = 1L;
    private int someProperty;

    public Subclass() {
    }

    public Subclass(int someProperty, String myProperty) {
        super(myProperty);
        this.someProperty = someProperty;
    }

    public int getSomeProperty() {
        return someProperty;
    }

    public void setSomeProperty(int someProperty) {
        this.someProperty = someProperty;
    }
}

public class Superclass implements Serializable {
    private static final long serialVersionUID = 1L;
    private String myProperty;

    public Superclass() {
    }

    public Superclass(String myProperty) {
        this.myProperty = myProperty;
    }

    public String getMyProperty() {
        return myProperty;
    }

    public void setMyProperty(String myProperty) {
        this.myProperty = myProperty;
    }
}

不应该失败,因为

Exception in thread "main" java.lang.IllegalArgumentException: class richtercloud.gson.exclusion.strategy.Subclass declares multiple JSON fields named serialVersionUID
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:170)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:100)
    at com.google.gson.Gson.getAdapter(Gson.java:423)
    at com.google.gson.Gson.toJson(Gson.java:661)
    at com.google.gson.Gson.toJson(Gson.java:648)
    at com.google.gson.Gson.toJson(Gson.java:603)
    at com.google.gson.Gson.toJson(Gson.java:583)
    at richtercloud.gson.exclusion.strategy.Main.main(Main.java:41)

如果如下使用串行化排除策略:

Gson gson = new GsonBuilder()
        .excludeFieldsWithModifiers(Modifier.TRANSIENT)
        .addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                boolean retValue = f.getName().equals("serialVersionUID");
                return retValue;
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        })
        .create();
Subclass a = new Subclass();
String response = gson.toJson(a);
System.out.println(response);

我用的是Gson 2.8.2.

hc8w905p

hc8w905p1#

分析

看来,这是一个众所周知的问题:

一些替代方案

解决方案1:适配器使用类型

这里推荐的解决方案(参见“分析”链接),即变通方案,是引入一个合适的类型适配器。

解决方案2:从序列化中排除静态字段

为什么不完全排除静态字段的序列化呢?

new GsonBuilder()
    // ...
    .excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC)
    // ...

解决方案3:仅序列化@Exposed字段

通过使用@Exposed注解并适当地配置GsonBuilder,可以显式地公开可序列化字段:

new GsonBuilder()
    // ...
    .excludeFieldsWithoutExposeAnnotation()
    // ...
hgtggwj0

hgtggwj02#

问题是您只调用了addSerializationExclusionStrategy,但是当Gson构建基于反射的内部适配器时,它考虑了序列化 * 和反序列化 *。因此,您还必须使用GsonBuilder.addDeserializationExclusionStrategy来注册反序列化的相同排除策略。

相关问题