Detailed Explanation of Three Ways of Designating Ignore Fields in Gson Serialization

  • 2021-12-04 10:08:38
  • OfStack

Directory 1. transient keyword 2. expose Notes 3. Custom troubleshooting policy ExclusionStrategy

In our daily use of the json serialization framework, we often encounter some fields ignored when outputting json strings. What can we do to achieve this in the Gson framework?

This article introduces several common postures

1. transient keyword

The most easily thought of case is to directly use the transient keyword of jdk to modify objects that do not want to be output, such as


@Data
@AllArgsConstructor
@NoArgsConstructor
public static class GItem {
    private String user;
    // @IgnoreField
    private transient String pwd;
}

In the above object, pwd is preceded by transient, so when outputting json string, it will be ignored by default
@Test


public void testPrint() {
    GItem item = new GItem("1 Grey ash ", "yihui");
    String ans = new Gson().toJson(item);
    System.out.println(ans);
}

Output such as

{"user": "1 Grey Grey"}

2. expose Notes

The above case can also be implemented with the expose annotation provided by gson, such as adding @ Expose to the fields that need to be retained


@Data
@AllArgsConstructor
@NoArgsConstructor
public static class GItem {
    @Expose
    private String user;
    // @IgnoreField
    private String pwd;
}

Then where we use it, pay attention to creating Gson objects through GsonBuilder


@Test
public void testPrint() {
    GItem item = new GItem("1 Grey ash ", "yihui");
    String ans = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(item);
    System.out.println(ans);
}

The above gesture feels a bit strange. Add comments to the fields that need to be kept. This way of using is not as convenient as the @ JsonIgnore way of jackson

3. Custom troubleshooting policy ExclusionStrategy

In addition to the above two approaches, a custom exclusion policy allows you to specify which fields are not serialized even without modifying the bean
A simple demo is as follows, not serialized if it contains custom annotations, or field_name = = pwd is not serialized either


@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface IgnoreField {
}


@Test
public void testExclude() {
    Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
        @Override
        public boolean shouldSkipField(FieldAttributes fieldAttributes) {
            if (fieldAttributes.getAnnotation(IgnoreField.class) != null) {
                //  Containing this annotation, ignore it directly 
                return true;
            }

            //  Member White List 
            if (fieldAttributes.getName().equalsIgnoreCase("pwd")) {
                return true;
            }
            return false;
        }

        @Override
        public boolean shouldSkipClass(Class<?> aClass) {
            if (aClass.isAnnotationPresent(IgnoreField.class)) {
                return true;
            }
            return false;
        }
    }).registerTypeAdapterFactory(new MyMapTypeAdapterFactory(new ConstructorConstructor(new HashMap<>()), false)).create();

    GItem item = new GItem();
    item.setUser("1 Grey ash ");
    item.setPwd("123456");

    System.out.println(gson.toJson(item));
}

The above posture is more suitable for case with custom requirements scenarios, so the problem comes. If the object I want to serialize is not an JOPO object, for example, an Map is passed in, and I also want to ignore some key, what can I do?


Related articles: