Gson: How to exclude specific fields from Serialization without annotations

后端 未结 15 1628
后悔当初
后悔当初 2020-11-22 05:39

I\'m trying to learn Gson and I\'m struggling with field exclusion. Here are my classes

public class Student {    
  private Long                id;
  privat         


        
15条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-22 06:21

    So, you want to exclude firstName and country.name. Here is what your ExclusionStrategy should look like

        public class TestExclStrat implements ExclusionStrategy {
    
            public boolean shouldSkipClass(Class arg0) {
                return false;
            }
    
            public boolean shouldSkipField(FieldAttributes f) {
    
                return (f.getDeclaringClass() == Student.class && f.getName().equals("firstName"))||
                (f.getDeclaringClass() == Country.class && f.getName().equals("name"));
            }
    
        }
    

    If you see closely it returns true for Student.firstName and Country.name, which is what you want to exclude.

    You need to apply this ExclusionStrategy like this,

        Gson gson = new GsonBuilder()
            .setExclusionStrategies(new TestExclStrat())
            //.serializeNulls() <-- uncomment to serialize NULL fields as well
            .create();
        Student src = new Student();
        String json = gson.toJson(src);
        System.out.println(json);
    

    This returns:

    { "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91}}
    

    I assume the country object is initialized with id = 91L in student class.


    You may get fancy. For example, you do not want to serialize any field that contains "name" string in its name. Do this:

    public boolean shouldSkipField(FieldAttributes f) {
        return f.getName().toLowerCase().contains("name"); 
    }
    

    This will return:

    { "initials": "P.F", "country": { "id": 91 }}
    

    EDIT: Added more info as requested.

    This ExclusionStrategy will do the thing, but you need to pass "Fully Qualified Field Name". See below:

        public class TestExclStrat implements ExclusionStrategy {
    
            private Class c;
            private String fieldName;
            public TestExclStrat(String fqfn) throws SecurityException, NoSuchFieldException, ClassNotFoundException
            {
                this.c = Class.forName(fqfn.substring(0, fqfn.lastIndexOf(".")));
                this.fieldName = fqfn.substring(fqfn.lastIndexOf(".")+1);
            }
            public boolean shouldSkipClass(Class arg0) {
                return false;
            }
    
            public boolean shouldSkipField(FieldAttributes f) {
    
                return (f.getDeclaringClass() == c && f.getName().equals(fieldName));
            }
    
        }
    

    Here is how we can use it generically.

        Gson gson = new GsonBuilder()
            .setExclusionStrategies(new TestExclStrat("in.naishe.test.Country.name"))
            //.serializeNulls()
            .create();
        Student src = new Student();
        String json = gson.toJson(src);
        System.out.println(json); 
    

    It returns:

    { "firstName": "Philip" , "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91 }}
    

提交回复
热议问题