Gson尝试解析带@Expose(false)注释的字段并崩溃

时间:2018-07-15 20:45:53

标签: android json gson

我正在尝试使用Gson将一个非常基本的对象序列化为JSON。

这是班上

@org.greenrobot.greendao.annotation.Entity
public class Giveaway {

    @Id(autoincrement = true)
    @Expose(serialize = false,deserialize = false)
    private Long id;

    @NotNull
    private String owner;

    private Date raffleDate;
    private String thumbnailUrl;

    @ToMany(referencedJoinProperty = "giveawayId")
    private List<Influencer> mustFollowList;


    @NotNull
    @Convert(converter = GiveawayCommentTypeConverter.class, columnType = Integer.class)
    private GiveawayCommentType tipo;


    private String specifWordValue;
    private Integer amountFriendsToIndicate;

    @NotNull
    @Unique
    private String mediaId;


    //to reflect the relationships
    @ToMany(referencedJoinProperty = "raffle")
    @Expose(deserialize = false, serialize = false)
    private List<UserOnGiveaway> attendantsTickets;
}

正如您所看到的,我有2个字段我不想序列化,所以我用expose = false对其进行了注释,但是即使如此,Gson仍试图对它们进行序列化并由于OutOfMemory而崩溃。 (UserOnGiveaway与Giveaway有一个循环引用,这说明了崩溃的原因。)

Gson代码为:

        Gson parser = new GsonBuilder().setPrettyPrinting().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.TRANSIENT).create();
        StringBuilder sb = new StringBuilder(200);
        try {
            for (Giveaway g : this.dao.getGiveawayDao().loadAll())
                sb.append(parser.toJson(g) + "\n");
        } catch (Exception e) {
            e.printStackTrace();
        }

我不想使用.excludeFieldsWithoutExposeAnnotation(),因为它迫使我编写超出必要范围的文字,并注释所有内容以仅排除1个字段...

我在做什么错了?

2 个答案:

答案 0 :(得分:0)

在您的transient字段上使用attendantsTickets Java关键字,不要为您的情况使用@Expose

摘自文档https://github.com/google/gson/blob/master/UserGuide.md: “如果字段被标记为瞬态,(默认情况下)它将被忽略,并且不包含在JSON序列化或反序列化中。”

private transient List<UserOnGiveaway> attendantsTickets;

也请查看以下Gson配置选项:GsonBuilder.excludeFieldsWithModifiers(int... modifiers)

有关Java中transient的更多信息,您可以在这里https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.3


如果您的代码基于瞬时行为(例如JPA或其他数据映射工具),则必须使用Gson排除策略。

您可以创建注释并在其中标记受自定义序列化影响的字段,然后在排除策略代码中使用它:

    @Target(value = ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface ExcludeFromJson {
    }

.........

    void gson() {

        new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
          @Override
          boolean shouldSkipField(FieldAttributes f) {
            return f.getAnnotation(ExcludeFromJson.class) != null;
          }

          @Override
          boolean shouldSkipClass(Class<?> clazz) {
            return false;
          }
        })
      }

..........

@ExcludeFromJson
private transient List<UserOnGiveaway> attendantsTickets;

答案 1 :(得分:0)

excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.TRANSIENT)

它声明是否将任何变量声明为final,static或transient都不会序列化(和反序列化)。 因此,代替@Expose注释

@Expose(deserialize = false, serialize = false)

使用以上三个关键字中的任何一个,即:

private transient Long id;