spring-mvc序列化json動(dòng)態(tài)擦除屬性.docx_第1頁
spring-mvc序列化json動(dòng)態(tài)擦除屬性.docx_第2頁
spring-mvc序列化json動(dòng)態(tài)擦除屬性.docx_第3頁
spring-mvc序列化json動(dòng)態(tài)擦除屬性.docx_第4頁
spring-mvc序列化json動(dòng)態(tài)擦除屬性.docx_第5頁
已閱讀5頁,還剩7頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

項(xiàng)目結(jié)構(gòu):spring-mvc + mybaties(annotation-driven), 返回給客戶端序列化的json串問題背景:由于項(xiàng)目本身性質(zhì),后臺(tái)程序返回給前臺(tái)的時(shí)候,返回了一大堆沒用的屬性。為了節(jié)約網(wǎng)絡(luò)流量,需要對(duì)多余的屬性進(jìn)行擦除,最簡(jiǎn)單的辦法就是在將要序列化的對(duì)象的屬性設(shè)置為空,然后再序列化的時(shí)候排除空屬性即可(當(dāng)然也可以自己實(shí)現(xiàn)一個(gè)序列化插件,我比較懶,就用這種方法了)。由于這個(gè)業(yè)務(wù)是整個(gè)系統(tǒng)所公用的,所以考慮提取一個(gè)公共的方法,動(dòng)態(tài)去擦除屬性。問題解決方案:查閱了網(wǎng)上一些資料,綜合對(duì)比了一下,決定在controller外面加一個(gè)AOP代理攔截。在攔截器的Around方法里面對(duì)controller返回的結(jié)果進(jìn)行統(tǒng)一的擦除。基本思路:1、 給需要序列化的對(duì)象(例如,對(duì)象A)添加一種使用場(chǎng)景,使用注解在這個(gè)對(duì)象上面指定每一種場(chǎng)景需要保留或者需要擦除哪些屬性2、 每個(gè)使用到這個(gè)對(duì)象A的方法,都需要指定這個(gè)對(duì)象的場(chǎng)景。3、 通用的AOP根據(jù)這個(gè)場(chǎng)景,來查找到想要保留、擦除的屬性,然后通過給屬性設(shè)置空值進(jìn)行擦除。4、 場(chǎng)景跟要保留或者擦除的屬性得映射,可以通過注解,也可以通過配置文件,本質(zhì)上是差不多的,這里采用注解。通用組件共有這些類:代碼:JsonFilter.java,這個(gè)類是場(chǎng)景和屬性映射的集合package com.test.json;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;Retention(RetentionPolicy.RUNTIME)Target(ElementType.TYPE)public interface JsonFilter public JsonFilterEntry value(); JsonFilterEntry.java,每個(gè)場(chǎng)景對(duì)應(yīng)一個(gè)這個(gè)注解,這個(gè)注解是場(chǎng)景與屬性的映射package com.test.json;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/* * 指示需要擦除哪些屬性 * * 如果指定了includes, 則以includes為準(zhǔn) * 如果未指定includes,指定了excludes,則以excludes為準(zhǔn) * 如果都沒有指定,則不擦除任何屬性 * * author wisdom * */Retention(RetentionPolicy.RUNTIME)public interface JsonFilterEntry /* * key * return */ public String key() default basic; /* * 保留哪些屬性 * return */ public String includes() default ; /* * 排除哪些屬性 * return */ public String excludes() default ;Eraseable.java,實(shí)現(xiàn)了這個(gè)接口的類才可以被擦除,否則不被擦除。這個(gè)接口返回一個(gè)type,擦除的時(shí)候根據(jù)這個(gè)type去查找保留或者刪除的屬性。package com.test.json;public interface Eraseable public String getEraseType(); JsonFilterParser.java, 用來掃描指定的包里面的類,獲取到關(guān)心的注解package com.test.json;import java.util.Arrays;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import com.test.dal.util.PackageScan;public class JsonFilterParser private static final MapString, Map ANNOTATION_MAP = new HashMapString, Map(); /* * 預(yù)先把這些東西加載上, 這個(gè)方法一般在系統(tǒng)啟動(dòng)的時(shí)候調(diào)用一次即可 * param packages */ public static synchronized void reload(String packages) if(packages != null & packages.length 0) List classes = new LinkedList(); for(String p : packages) classes.addAll(PackageScan.getClassNames(p, true); if(classes.size() 0 & ANNOTATION_MAP.size() 0) ANNOTATION_MAP.clear(); for(String s : classes) parseClass(s); /* * 解析 * param classpath */ SuppressWarnings(rawtypes, unchecked) private static void parseClass(String classpath) if(ANNOTATION_MAP.containsKey(classpath) return; try Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classpath); if(clazz != null) JsonFilter filters = (JsonFilter) clazz.getAnnotation(JsonFilter.class); if(filters != null) JsonFilterEntry entrys = filters.value(); Map map = new HashMap(); for(JsonFilterEntry entry : entrys) String key = entry.key(); JsonFilterEntity en = new JsonFilterEntity(); en.setKey(key); en.getIncludes().addAll(Arrays.asList(entry.includes(); en.getExcludes().addAll(Arrays.asList(entry.excludes(); map.put(key, en); ANNOTATION_MAP.put(classpath, map); catch (ClassNotFoundException e) e.printStackTrace(); public static Map getFilters(String classpath) return ANNOTATION_MAP.get(classpath); public static JsonFilterEntity getFilter(String classpath, String type) Map m = getFilters(classpath); if(m != null) return m.get(type); return null; public static void main(String args) reload(new Stringcom.test.bean.ext); JsonFilterEntity.java, 一個(gè)數(shù)據(jù)結(jié)構(gòu),用于緩存JsonFilterEntry的值package com.test.json;import java.util.HashSet;import java.util.Set;public class JsonFilterEntity private String key; private Set includes = new HashSet(); private Set excludes = new HashSet(); public String getKey() return key; public void setKey(String key) this.key = key; public Set getIncludes() return includes; public void setIncludes(Set includes) this.includes = includes; public Set getExcludes() return excludes; public void setExcludes(Set excludes) this.excludes = excludes; BeanEraseUtil.java,擦除的工具類,用的時(shí)候,調(diào)用BeanEraseUtil.erase(obj)即可package com.test.json;import java.beans.BeanInfo;import java.beans.IntrospectionException;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Collection;import java.util.Map;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.test.ww.util.BeanUtil;import com.test.ww.util.StringUtil;public class BeanEraseUtil private static final Logger logger = LoggerFactory.getLogger(BeanUtil.class); private static final Object EMPTY_ARRAY_WRITE=new Objectnull; private static final Object EMPTY_ARRAY_READ=new Object; private static final MapClass,PropertyDescriptor map=new ConcurrentHashMapClass,PropertyDescriptor(); public static PropertyDescriptor getPropDescs(Class c) throws IntrospectionException PropertyDescriptor propDescs=map.get(c); if(propDescs=null) BeanInfo info=Introspector.getBeanInfo(c,Introspector.IGNORE_ALL_BEANINFO); propDescs=info.getPropertyDescriptors(); map.put(c,propDescs); return propDescs; /* * 擦除的總?cè)肟?* param obj */ public static void erase(Object obj) if(obj = null) return; boolean eraseSub = true; if(obj instanceof Class) return; if(obj.getClass().isArray()/數(shù)組 Object objarray = (Object) obj; for(Object o : objarray) if(!go(o) break; erase(o); eraseSub = false; else if(obj instanceof Collection)/集合 Collection coll = (Collection) obj; for(Object o : coll) if(!go(o) break; erase(o); eraseSub = false; else if(obj instanceof Eraseable) Eraseable e = (Eraseable) obj; String type = e.getEraseType(); if(StringUtil.isEmpty(type) type = basic; JsonFilterEntity entity = JsonFilterParser.getFilter(obj.getClass().getName(), type); if(entity != null) eraseObject(obj, entity.getIncludes(), entity.getExcludes(); if(eraseSub) try PropertyDescriptor arr=getPropDescs(obj.getClass(); for(PropertyDescriptor d:arr) Method m = d.getReadMethod(); if(m != null) Object val = m.invoke(obj, EMPTY_ARRAY_READ); if(val != null) if(go(val) erase(val); catch (IntrospectionException e) e.printStackTrace(); catch (IllegalAccessException e) e.printStackTrace(); catch (IllegalArgumentException e) e.printStackTrace(); catch (InvocationTargetException e) e.printStackTrace(); /* * 是否繼續(xù) * param o * return */ private static boolean go(Object o) if(o = null) return false; if(o instanceof Eraseable) return true; if(o.getClass().isArray() return true; if(o instanceof Collection) return true; return false; private static void eraseObject(Object obj, Set includes, Set excludes) if(obj = null) return; try PropertyDescriptor arr=getPropDescs(obj.getClass(); for(PropertyDescriptor d:arr) String name=d.getName(); if(needErase(name, includes, excludes) Method m=d.getWriteMethod(); if(m=null) continue; m.invoke(obj,EMPTY_ARRAY_WRITE); catch (Exception e) logger.error(attr erase errror,e); throw new RuntimeException(attr erase exception, e); /* * 返回true, 擦除, false, 保留 * param name * param includes * param excludes * return */ private static boolean needErase(String name, Set includes, Set excludes) if(class.equals(name) | serialVersionUID.equals(name) return false; if(includes != null & includes.size() 0)/指定了includes, 以includes為準(zhǔn) return !includes.contains(name); else if(excludes != null & excludes.size() 0) return excludes.contains(name); return false; 至此,spring-mvc動(dòng)態(tài)擦除對(duì)象的組件就已經(jīng)完成。在controller外面加一個(gè)aop攔截,獲取到每個(gè)controller的返回值,然后調(diào)用BeanEraseUtil.erase(obj)即可。用法示例:package com.test.bean.ext;import java.util.ArrayList;import java.util.List;import com.test.constant.TagConstant;import com.test.dal.model.Tag;import com.test.json.Eraseable;import com.test.json.JsonFilter;import com.test.json.JsonFilterEntry;import com.test.service.base.NameNoted;import com.test.service.tag.Tagable;JsonFilter( JsonFilterEntry(key=basic, excludes=createTime, isValid, tags), Json

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論