Gson: How to exclude specific fields from Serialization without annotations
Any fields you don't want serialized in general you should use the "transient" modifier, and this also applies to json serializers (at least it does to a few that I have used, including gson).
If you don't want name to show up in the serialized json give it a transient keyword, eg:
private transient String name;
Nishant provided a good solution, but there's an easier way. Simply mark the desired fields with the @Expose annotation, such as:
@Expose private Long id;
Leave out any fields that you do not want to serialize. Then just create your Gson object this way:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
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 }}