上一篇写的Json转换项目中大部分情况都已经够用了,但是,有时候一个对象很多属性,而我们并不需要那么多,那么就选择性的过滤掉一些属性喽。
还有对于日期这样的属性,我们该让它以何种格式显示呢? 这也是我们需要考虑的问题。
下面请看实例:
实体类Student.java
public class Student { @Include("tt") private String userName; @Exclude("tt") private int age; @Include("tt") private Date birthDay; private List<String> hobbiy; /////////////////get/set方法已经省略///////////////////////// }
我们采用注解的方式,在实体类上加上一个注解,加了注解的表示要转换成Json的,没加的则不转换,而且可以灵活的控制。
注解类:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Include { String[] value() default ""; }
转换类:
public class JsonInclude { private static Map<String,List<String>> classfields=new HashMap<String,List<String>>(); private JsonInclude() { } /** * * @param obj * @param includeTag 只将Include标签中包含此字符串的field转换成json 为null时将不过滤 * @return */ public static Object json(Object obj, String includeTag) { try { if (null != obj) { JsonConfig jsonConfig=null; if(StringUtils.isEmpty(includeTag)) jsonConfig=getJsonConfig(); else jsonConfig=getJsonConfig(includeTag); jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor()); if (obj instanceof List ) { return JSONArray.fromObject(obj, jsonConfig); } else { return JSONObject.fromObject(obj, jsonConfig); } } return obj; } catch (Exception e) { System.out.println("json failed " + includeTag); System.out.println(e.getLocalizedMessage()); System.out.println(e); } return obj; } private static JsonConfig getJsonConfig(final String includeTag) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setJsonPropertyFilter(new PropertyFilter(){ @Override public boolean apply(Object obj, String name, Object value) { if(value == null){ return true; }else{ Class<?> objClass=obj.getClass(); Class<?> tempClass=obj.getClass(); List<String> fields=classfields.get(objClass.getName()+includeTag); if(CollectionUtils.isEmpty(fields)){ fields=new ArrayList<String>(); while(objClass!=null){ Field[] fieldss=objClass.getDeclaredFields(); for(Field f:fieldss){ if(f.isAnnotationPresent(Include.class)){ String[] tag = f.getAnnotation(Include.class).value(); for (String str : tag) { if (str.equals(includeTag)) { fields.add(f.getName()); break; } } } } objClass=objClass.getSuperclass(); } classfields.put(tempClass.getName()+includeTag, fields); } for(String ff:fields){ if(ff.equals(name)){ return false; } } return true; } } }); return jsonConfig; } private static JsonConfig getJsonConfig() { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setJsonPropertyFilter(new PropertyFilter(){ @Override public boolean apply(Object obj, String name, Object value) { return null==value; } }); return jsonConfig; } }
这里面用到了日期格式转换的类,等最后面会贴出来。
现在就可以看测试类了:
public class IncludeTest { //所有属性都会转换 public void objectNoTag(){ Student s = new Student(); s.setAge(45); s.setBirthDay(new Date()); List<String> hobbiy = new ArrayList<String>(); hobbiy.add("唱歌");hobbiy.add("跳舞");hobbiy.add("爬山"); s.setHobbiy(hobbiy); s.setUserName("张三"); System.out.println(JsonInclude.json(s, null)); } //现在只有属性上加有@Include("tt")注解的才会转换了 public void objectTag(){ Student s = new Student(); s.setAge(45); s.setBirthDay(new Date()); List<String> hobbiy = new ArrayList<String>(); hobbiy.add("唱歌");hobbiy.add("跳舞");hobbiy.add("爬山"); s.setHobbiy(hobbiy); s.setUserName("张三"); System.out.println(JsonInclude.json(s, "tt")); } public static void main(String[] args) { IncludeTest inc = new IncludeTest(); inc.objectNoTag(); inc.objectTag(); }
日期转换类:
public class JsonDateValueProcessor implements JsonValueProcessor { public JsonDateValueProcessor() { super(); } public JsonDateValueProcessor(String format) { super(); } @Override public Object processArrayValue(Object paramObject, JsonConfig paramJsonConfig) { return process(paramObject); } @Override public Object processObjectValue(String paramString, Object paramObject, JsonConfig paramJsonConfig) { return process(paramObject); } private Object process(Object value){ if(value instanceof Date){ return ((Date) value).getTime(); } return value == null ? "" : value.toString(); } }
可能会有人觉得如果我只想去掉某一个属性,那你不会让我把剩下的属性全加你那个注解吧? 当然不会。
我们可以再写一个嘛
注解类:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Exclude { String[] value() default ""; }
转换类:
public class JsonExclude { private static Map<String,List<String>> classfields=new HashMap<String,List<String>>(); private JsonExclude() {} /** * * @param obj * @param excludeTag 将过滤Exclude标签中包含此字符串的field的属 ?为null时将不过滤 * @return */ public static Object json(Object obj, String excludeTag) { try { if (null != obj) { JsonConfig jsonConfig=null; if(StringUtils.isEmpty(excludeTag)) jsonConfig=getJsonConfig(); else jsonConfig=getJsonConfig(excludeTag); jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor()); if (obj instanceof List) { return JSONArray.fromObject(obj, jsonConfig); } else { return JSONObject.fromObject(obj, jsonConfig); } } return obj; } catch (Exception e) { System.out.println("json failed . excludeTag={},msg={}" + excludeTag + e.getLocalizedMessage() + e); } return obj; } private static JsonConfig getJsonConfig(final String excludeTag) { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setJsonPropertyFilter(new PropertyFilter(){ @Override public boolean apply(Object obj, String name, Object value) { if(value == null){ return true; }else{ Class<?> objClass=obj.getClass(); Class<?> tempClass=obj.getClass(); List<String> fields=classfields.get(objClass.getName()+excludeTag); if(CollectionUtils.isEmpty(fields)){ fields=new ArrayList<String>(); while(objClass!=null){ Field[] fieldss=objClass.getDeclaredFields(); for(Field f:fieldss){ if(f.isAnnotationPresent(Exclude.class)){ String[] tag = f.getAnnotation(Exclude.class).value(); for (String str : tag) { if (str.equals(excludeTag)) { fields.add(f.getName()); break; } } } } objClass=objClass.getSuperclass(); } classfields.put(tempClass.getName()+excludeTag, fields); } for(String ff:fields){ if(ff.equals(name)){ return true; } } return false; } } }); return jsonConfig; } private static JsonConfig getJsonConfig() { JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setJsonPropertyFilter(new PropertyFilter(){ @Override public boolean apply(Object obj, String name, Object value) { return null==value; } }); return jsonConfig; } }
测试:
public class ExcludeTest { public void listTag(){ Student s0 = new Student(); s0.setAge(45); s0.setBirthDay(new Date()); List<String> hobbiy0 = new ArrayList<String>(); hobbiy0.add("唱歌");hobbiy0.add("跳舞");hobbiy0.add("爬山"); s0.setHobbiy(hobbiy0); s0.setUserName("张三"); Student s1 = new Student(); s1.setAge(35); s1.setBirthDay(new Date()); List<String> hobbiy1 = new ArrayList<String>(); hobbiy1.add("唱歌1");hobbiy1.add("跳舞1");hobbiy1.add("爬山1"); s1.setHobbiy(hobbiy1); s1.setUserName("李四"); Student s2 = new Student(); s2.setAge(25); s2.setBirthDay(new Date()); List<String> hobbiy2 = new ArrayList<String>(); hobbiy2.add("唱歌2");hobbiy2.add("跳舞2");hobbiy2.add("爬山2"); s2.setHobbiy(hobbiy2); s2.setUserName("王五"); List<Student> list = new ArrayList<Student>(); list.add(s0);list.add(s1);list.add(s2); System.out.println(JsonExclude.json(list, "tt")); } public static void main(String[] args) { ExcludeTest exc = new ExcludeTest(); exc.listTag(); }