GsonBuilder 中的执行策略未应用

Execution strategy in GsonBuilder is not applied

提问人:iuhztr tzhjzuk 提问时间:10/2/2023 更新时间:10/3/2023 访问量:40

问:

我有以下示例:

public class A implements Serializable {
    int a;
    B b;
    ...

    @Override
    public String toString() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

}
public class B implements Serializable {
    int c;
    byte[] d;
    ...

    @Override
    public String toString() {
        Gson gson = new GsonBuilder().setExclusionStrategies(new BExclusionStrategy()).create();
        return gson.toJson(this);
    }

    public class BExclusionStrategy implements ExclusionStrategy {
    @Override
    public boolean shouldSkipClass(Class<?> arg0) {
        return false;
    }

    @Override
    public boolean shouldSkipField(FieldAttributes attr) {
        return attr.getName().equals("d") && attr.getDeclaringClass() == B.class;
    }
    }
}

我想在调用类 A 的方法时排除字段 d,因为字节数组非常长。但是如果我在类 B 中指定执行策略,则在调用时不适用。但是,如果我将执行策略移动到类 A 的方法,它确实有效,并且省略了字段 d。toStringA.toString()toString

为什么会这样?此外,B 类用于多个不同的类,我想省略所有类的打印 d。

为什么会这样?此外,B 类用于多个不同的类,我想省略所有类的打印 d。

注意:我不想使用,但这可以解决打印问题。我也尝试了 B 类的其他文件@Exclude,但它也没有用。transient byte[] dexcludeFieldsWithoutExposeAnnotation()

java json 序列化 gson

评论


答:

0赞 Marcono1234 10/3/2023 #1

但是如果我在类 B 中指定执行策略,则在调用时不适用。但是,如果我将执行策略移动到类 A 的方法,它确实有效,并且省略了字段 d。A.toString()toString

为什么会这样?

因为当你调用 which 调用 Gson 时,它使用反射来序列化 and then 的字段。由于这永远不会被调用,因此您指定的排除策略不起作用。A.toString()ABB.toString()

我还尝试了 B 类其他领域的@Exclude

Gson 没有注解,只有@Expose。该注释可能来自不同的库,但 Gson 会忽略它。@Exclude@Exclude

最简单的解决方案是使用字段修饰符。如果您不想这样做,则可以改为创建一个配置了自定义排除策略的 Gson 实例,然后所有方法都使用该实例。您还可以通过创建自己的注释或类似内容并让排除策略进行检查来使排除策略更通用。transienttoString()@Exclude

但是,由于您关心的似乎是字节数组的长度,因此您也可以在该字段上使用 Gson 的 @JsonAdapter 注释来指定自定义适配器,该适配器可以创建更简洁的数组 JSON 表示形式。byte[] d