咱們團隊如今面臨着多端數據接口對接的問題,爲了解決這個問題咱們定義了接口對接的規範,
前端(安卓,Ios,web前端)和後端進行了數據的格式規範的討論,肯定了json的數據格式:前端
{ "code":"200", "data":{"":""}, "message":"處理成功" } { "code":"300", "data":{"":""}, "message":"沒有此用戶" }
code表明請求處理狀態:200爲正常處理,300爲業務異常處理,500就係統異常處理。
data表明後臺返回的數據。
message後臺的提示語,正常或者成功的時候會返回錯誤緣由。web
讓每個人對每個json視圖的返回值都要進行包裝的話,豈不很麻煩,
這個時候AOP就登場了,咱們能夠利用aop的思想在請求返回json以後還未response到客戶端時爲其包裝上一層。spring
<!-- base-package 若是多個,用「,」分隔 --> <context:component-scan base-package="com.we,cn.isuyang"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan> <!-- 打開aop 註解 --> <aop:aspectj-autoproxy />
/** * json返回切面 * <p> * 用於處理json返回結果 * * @author ZhuangJunxiang(529272571@qq.com) * @Date 2017年4月28日 */ @Component @Aspect @Order(2) public class JsonReturnAspect { /** * 設置分頁默認值 * <p> * 若是分頁沒有設置值,則默認從系統的配置文件裏讀取 * * @param pjp 切點 */ @Around(value = "@annotation(org.springframework.web.bind.annotation.ResponseBody)") @Order(1) public Object warp(final ProceedingJoinPoint pjp) throws Throwable { Object list = pjp.proceed(); if (isReturnVoid(pjp)) { HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getResponse(); if (isNeedWrap(pjp)) { response.getWriter().write(JsonUtil.toJson(success("操做成功"))); } return list; } return data(list); } /** * 是否須要包裹 * * @param pjp 切點 * * @return true表示不須要 */ private boolean isNeedWrap(final ProceedingJoinPoint pjp) { Method method = AspectUtil.getMethod(pjp); return !method.isAnnotationPresent(Void.class); } /** * 是否返回空 * * @param pjp * @return true:返回類型爲void,false:返回類型不是void */ private boolean isReturnVoid(ProceedingJoinPoint pjp) { Method method = AspectUtil.getMethod(pjp); Class<?> returnType = method.getReturnType(); return "void".equals(returnType.getName()); } /** * 構建成功後的返回對象 * <p> * 消息爲空時,不提示,不爲空則進行提示 * * @param message 成功消息 * @return json對象 */ public static Map<String, Object> success(final String message) { Map<String, Object> map = MapUtil.map(); map.put("code", StatusCode.SUCCESS.key()); map.put("message", message); map.put("data",""); return map; } /** * 構建成功後的返回對象 * <p> * 消息爲空時,不提示,不爲空則進行提示 * * @param message 成功消息 * @return json對象 */ public static Map<String, Object> data(final Object data) { Map<String, Object> map = MapUtil.map(); map.put("code", StatusCode.SUCCESS.key()); map.put("message", message); map.put("data",data); return map; } }
@Component 這個註解表示將這個對象交給spring容器進行實例化express
@Aspect 表示這是一個切面類json
@Around(value = "@annotation(org.springframework.web.bind.annotation.ResponseBody)")後端
表示凡是方法上帶有@ResponseBody註解的都是這個切面中切點,換句話說都會被攔截。app
注意:
warp方法中的ProceedingJoinPoint參數只有環繞通知纔可使用JoinPoint的子類ProceedingJoinPoint,
各鏈接點類型能夠調用代理的方法,並獲取、改變返回值。不然就是用JoinPoint。函數
好比:我對一個實體對象進行更新我只須要把更新結果返回去就OK了,不須要填充數據
返回的數據格式:
{
"code":"200",
"data":"",
"message":"處理成功"
}
實現思路:
在切面處理類的處理函數中獲取到這個函數的返回值類型若是是void就返回指定格式的數據。
上面的isReturnVoid()就是作這樣的一個判斷。.net
你只須要將函數的返回值爲void便可:插件
@RequestMapping @ResponseBody public void add(long matchId, Model model) { slxSignupViewService.setAddInfo(matchId, model); }
好比:
某些前端插件以及第三方對接(支付)的返回值是規定好的,
以及下載文件,咱們這些就是多餘了,
實現思路:
自定一個@Void的註解:
/** * 空註解 * <p> * 用於標識將controller層中的返回值原模原樣的out出去 * * @author WangSen(wangsenhehe@126.com) * @Date 2017年8月17日 */ @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Void { }
在controller層的方法上添加這個註解
/** * 支付完成 */ @Void @ResponseBody @RequestMapping public void payFinish() throws IOException { alipayViewService.payFinish(); }
在這個切面處理類上判斷這個函數是否包含這個註解若是包含
就不做處理,原模原樣的返回出去。
JsonReturnAspect類中的isNeedWrap()方法就是處理這個需求。
http://blog.csdn.net/zx13525079024/article/details/51884234