我正在尝试学习Gson,并且在领域排除方面苦苦挣扎。这是我的课
public class Student { private Long id; private String firstName = "Philip"; private String middleName = "J."; private String initials = "P.F"; private String lastName = "Fry"; private Country country; private Country countryOfBirth; } public class Country { private Long id; private String name; private Object other; }
我可以使用GsonBuilder并为诸如firstName或的字段名称添加ExclusionStrategy,country但是我似乎无法设法排除诸如的某些字段的属性country.name。
GsonBuilder
firstName
ExclusionStrategy
country
country.name
使用该方法public boolean shouldSkipField(FieldAttributes fa),FieldAttributes包含的信息不足,无法使用过滤器将该字段匹配country.name。
public boolean shouldSkipField(FieldAttributes fa),FieldAttributes
PS:我想避免使用注释,因为我想对此进行改进,并使用RegEx过滤掉字段。
编辑:我试图看看是否有可能模拟Struts2 JSON插件的行为
使用Gson
<interceptor-ref name="json"> <param name="enableSMD">true</param> <param name="excludeProperties"> login.password, studentList.*\.sin </param> </interceptor-ref>
编辑: 我重新打开了以下添加的问题:
我添加了第二个具有相同类型的字段,以进一步阐明此问题。基本上我想排除country.name但不排除countrOfBirth.name。我也不想将“国家”作为一种类型排除在外。因此,类型与我要查明和排除的对象图中的实际位置相同。
countrOfBirth.name
因此,你要排除 firstName和country.name。这是你的ExclusionStrategy样子
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")); } }
如果你仔细看它返回true的Student.firstName和Country.name,这是要排除的东西。
Student.firstName
Country.name
你需要应用此ExclusionStrategy这样,
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);
返回:
{ "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91}}
我假设国家对象id = 91L在学生课堂中进行了初始化。
你可能会喜欢上。例如,你不想序列化名称中包含“ name”字符串的任何字段。做这个:
public boolean shouldSkipField(FieldAttributes f) { return f.getName().toLowerCase().contains("name"); }
这将返回:
{ "initials": "P.F", "country": { "id": 91 }}
编辑:根据要求添加了更多信息。
这样ExclusionStrategy就可以了,但是你需要传递“完全合格的字段名称”。见下文:
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)); } }
这就是我们如何通用地使用它。
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);
它返回:
{ "firstName": "Philip" , "middleName": "J.", "initials": "P.F", "lastName": "Fry", "country": { "id": 91 }}
一般而言,你不希望序列化的任何字段都应使用“ transient”修饰符,这也适用于json序列化器(至少它适用于我使用过的少数几个,包括gson)。
如果你不希望名称显示在序列化的json中,请给它一个瞬态关键字,例如:
private transient String name;