自定義註解,實現攔截器
阿新 • • 發佈:2019-02-17
資訊網站專案
存在登入和未登入兩種狀態的操作,呼叫後臺方法需要進行判定是否登入。 此時攔截器派上用場
//攔截器用處(來源:跟著開濤學SpringMVC)
1、日誌記錄:記錄請求資訊的日誌,以便進行資訊監控、資訊統計、計算PV(Page View)等。
2、許可權檢查:如登入檢測,進入處理器檢測檢測是否登入,如果沒有直接返回到登入頁面;
3、效能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄);
4、通用行為:讀取cookie得到使用者資訊並將使用者物件放入請求,從而方便後續流程使用,還有如提取Locale、Theme資訊等,只要是多個處理器都需要的即可使用攔截器實現。
5、OpenSessionInView:如Hibernate,在進入處理器開啟Session,在完成後關閉Session。
…………本質也是AOP(面向切面程式設計),也就是說符合橫切關注點的所有功能都可以放入攔截器實現。
HandlerInterceptorAdapter
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
}
分別實現預處理、後處理(呼叫了Service並返回ModelAndView,但未進行頁面渲染)、返回處理(已經渲染了頁面)
在preHandle中,可以進行編碼、安全控制等處理;
在postHandle中,有機會修改ModelAndView;
在afterCompletion中,可以根據ex是否為null判斷是否發生了異常,進行日誌記錄。
//自定義註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NeedLogin {
String value() default "";
}
//攔截器,繼承HandlerInterceptorAdapter介面
public class LoginInterceptor extends HandlerInterceptorAdapter{
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
if(handler.getClass().isAssignableFrom(HandlerMethod.class)){//如果是spring mvc 方法
NeedLogin needLogin = ((HandlerMethod)handler).getMethodAnnotation(NeedLogin.class);
if(needLogin!=null){
NewsUser u = (NewsUser) request.getSession().getAttribute("user");
if(u==null){
String rt = request.getHeader("X-Requested-With");
if(rt!=null && "XMLHttpRequest".equals(rt)){
JSONObject json = new JSONObject();
json.put("isLogin", false);
response.getWriter().print(json.toString());
return false;
}else{
response.sendRedirect(request.getContextPath()+"/news/index");
return false;
}
}else{
return true;
}
}
}
return true;
}
}
根據以上寫法:
1.如果寫了@NeedLogin註解,則呼叫方法之前會進行是否登入校驗
2.未寫,則不校驗
@NeedLogin
@ResponseBody
@RequestMapping(value="addOrUpdate")
public String addHistory(Long roomId, Long userId) {
JSONObject obj = new JSONObject();
boolean flag = false;
ZhiboWatchRecord zhiboWatchRecord = zhiboWatchRecordService
.addOrUpdateToHistory(roomId, userId);
if (zhiboWatchRecord != null) {
flag = true;
}
obj.put("status", flag? 1:0);
return obj.toString();
}