項目中web網頁請求,action層返回的是同一個對象,WebApiBaseResult,並使用相同的異常處理
@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
,HttpServletRequest request
,@RequestParam(value = "condition",required = false)String condition
,@RequestParam(value = "keyword",required = false)String keyword){
WebApiBaseResult result = new WebApiBaseResult();//web統一返回對象
try{
BaseUserModel baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
if(null == baseUser){
throw new NotLogException("用戶登錄過期,請重新登錄");
}
//獲取session中的登錄公司的信息
BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
//業務代碼
....................
result.setData(data);//返回數據統一放在data裏
}catch(NotLogException e){
logger.error(MyRequestUtils.getParameterString());
logger.error(e.getMessage(),e);
result.setStatusCode(StatusCodeEnum.NOTLOG.getCode());
result.setMessage(e.getMessage());
return result;
}catch(Exception e){
logger.error(MyRequestUtils.getParameterString());
logger.error(e.getMessage(),e);
result.setStatusCode(StatusCodeEnum.COMMONERROR.getCode());
result.setMessage(e.getMessage());
return result;
}
return result;
}
所有的web請求都是如此處理的,雖然複製粘貼一下也不費什麼事,但是主管還是想複用一下,代碼看起來也清爽一點,於是我參考了一下過去項目的實現代碼,基本原理就是匿名函數和代理的編程思想的結合。
首先是寫一個接口,專門用來當匿名函數的
public interface BaseActionCallBack {
WebApiBaseResult run() throws Exception;
}
就這麼簡單,也不用實現,是專門當匿名函數用的。
再寫一個代理類
public class BaseActionProxy {
public static WebApiBaseResult commonWebAction(Logger logger, BaseActionCallBack action) {
WebApiBaseResult result = null;
try {
result = action.run();
} catch (NotLogException e) {
result = new WebApiBaseResult();
logger.error(MyRequestUtils.getParameterString());
logger.error(e.getMessage(), e);
result.setStatusCode(StatusCodeEnum.NOTLOG.getCode());
result.setMessage(e.getMessage());
} catch (Exception e) {
result = new WebApiBaseResult();
logger.error(MyRequestUtils.getParameterString());
logger.error(e.getMessage(), e);
result.setStatusCode(StatusCodeEnum.COMMONERROR.getCode());
result.setMessage(e.getMessage());
}
return result;
}
}
將上面寫的接口類當做參數傳進去,然後我還加了一個logger參數,打印異常用。
接着最開始的代碼就可以改造成這樣
@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
,HttpServletRequest request
,@RequestParam(value = "condition",required = false)String condition
,@RequestParam(value = "keyword",required = false)String keyword){
return BaseActionProxy.commonWebAction(logger, new BaseActionCallBack() {
@Override
public WebApiBaseResult run() throws Exception {
WebApiBaseResult result = new WebApiBaseResult();
BaseUserModel baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
if(null == baseUser){
throw new NotLogException("用戶登錄過期,請重新登錄");
}
//獲取session中的登錄公司的信息
BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
//業務代碼
....................
result.setData(data);//返回數據統一放在data裏
return result;
}
});
}
看起來是不是簡潔了很多,不過值得注意的是,匿名函數類裏面不能使用非finial的變量。java1.8比較智能一點,只要你沒有給變量賦值他就會視爲最終變量。這樣就會造成一些麻煩。比如分頁參數,因爲hibernate分頁是從0開始的,所以分頁參數傳進來後要減1,但是在匿名函數中就不能直接用了。
@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
,HttpServletRequest request
,@RequestParam(value = "condition",required = false)String condition
,@RequestParam(value = "keyword",required = false)String keyword
,@RequestParam(value = "page",required = false)Integer page){
return BaseActionProxy.commonWebAction(logger, new BaseActionCallBack() {
@Override
public WebApiBaseResult run() throws Exception {
WebApiBaseResult result = new WebApiBaseResult();
BaseUserModel baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
if(null == baseUser){
throw new NotLogException("用戶登錄過期,請重新登錄");
}
//獲取session中的登錄公司的信息
BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
Integer p = 0;//頁碼數需要減1,但是匿名函數中不能改變變量,所以只能聲明一個新的變量
if (page != null)
p = page -1;
PageParam pageInfo = new PageParam(p, size, pageFlag, sort);
//業務代碼
....................
result.setData(data);//返回數據統一放在data裏
return result;
}
});
}
只能聲明一個新的變量來接收,從這一點上看就不夠優雅了。相當於給代碼加了一個限制。。。其實還好,就是如果基本類型做更改需要聲明新變量接收,如果是對象,那麼還是能夠做更改的,就是其引用不能改變。
建議還是在action層中使用,然後把主要的業務代碼放到service層,action層只作爲傳遞參數的結構,這樣基本就不會出問題了。
完