使用Spring MVC 攔截器的原因
在controller
層操作時,經常要對用戶登錄信息進行判斷,如果每個controller
層都寫一次處理,就會出現代碼重複的現象。爲解決此問題,特引入Spring MVC 的攔截器 Interceptors
,對所有頁面進行處理,獲取用戶的登錄信息session
,方便後續操作。
實現步驟
- 定義
SessionInterceptor
類實現HandlerInterceptor
接口
在 HandlerInterceptor 接口中定義了三個方法來對用戶的請求進行攔截處理,其中:
preHandle()
在請求處理之前調用。其返回值是布爾值Boolean,當它返回爲false
時,表示請求結束,後續的Interceptor 和Controller 都不會再執行;當返回值爲true
時就會繼續調用下一個Interceptor 的preHandle 方法,如果已經是最後一個Interceptor 的時候就會調用當前請求的Controller方法postHandle()
當前所屬的Interceptor 的preHandle 方法的返回值爲true
時才能被調用。在當前請求進行處理之後,即Controller 方法調用之後、DispatcherServlet 進行視圖返回渲染之前被調用。可在該方法中對Controller 處理之後的ModelAndView 對象進行操作。afterCompletion()
當前對應的Interceptor的preHandle 方法的返回值爲true
時纔會執行。在整個請求結束之後,即在DispatcherServlet 渲染了對應的視圖之後執行。主要用於進行資源清理工作。
@Service
public class SessionInterceptor implements HandlerInterceptor {
@Autowired
private UserMapper userMapper;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在執行實際的處理程序之前,通過獲取到的cookie->token->數據庫是否存在 判斷用戶是否登錄
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length != 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
UserExample userExample = new UserExample();
userExample.createCriteria().andTokenEqualTo(token);
List<User> users = userMapper.selectByExample(userExample);
if (users.size() != 0) {
request.getSession().setAttribute("user", users.get(0));
}
break;
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
- 註冊攔截器以應用於傳入的請求,即將定義的攔截器配置到攔截體系中
@Configuration
//@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Autowired
SessionInterceptor sessionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPatterns() 對哪些文件進行攔截
// excludePathPatterns() 不對哪些文件攔截
registry.addInterceptor(sessionInterceptor).addPathPatterns("/**");
}
}
- 攔截處理後,在
controller
層的操作就簡單了。
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
return "redirect:/";
}