Home >Java >javaTutorial >Spring+SpringMVC+MyBatis in-depth learning and construction (17) - SpringMVC interceptor
Please indicate the source:
As mentioned earlier: Spring+SpringMVC+MyBatis in-depth learning and construction (16) - SpringMVC annotation development (advanced)
Spring Web MVC's processor interceptor is similar to the filter Filter in Servlet development, which is used to pre-process and post-process the processor.
Define the interceptor and implement the HandlerInterceptor interface. Three methods are provided in the interface.
<span style="color: #0000ff">package</span><span style="color: #000000"> joanna.yan.ssm.interceptor; </span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpServletRequest; </span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpServletResponse; </span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.servlet.HandlerInterceptor; </span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.servlet.ModelAndView; </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> HandlerInterceptor1 <span style="color: #0000ff">implements</span><span style="color: #000000"> HandlerInterceptor{ </span><span style="color: #008000">//</span><span style="color: #008000">执行Handler完成执行此方法 </span><span style="color: #008000">//</span><span style="color: #008000">应用场景:统一异常处理,统一日志处理</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......afterCompletion"<span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之后,返回modelAndView之前执行 </span><span style="color: #008000">//</span><span style="color: #008000">应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里同意指定视图</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......postHandle"<span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之前执行 </span><span style="color: #008000">//</span><span style="color: #008000">用于身份认证、身份授权 </span><span style="color: #008000">//</span><span style="color: #008000">比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不再向下执行。</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......preHandle"<span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000">return false表示拦截,不向下执行 </span><span style="color: #008000">//</span><span style="color: #008000">return true表示放行</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; } }</span>
There is a large interceptor chain in struts. It is a common thing. You can add it to any action link and let it intercept. But spring's interceptor is not global.
The springmvc interceptor performs interception settings for HandlerMapping. If interception is set in a HandlerMapping, the handler that is successfully mapped by the HandlerMapping will eventually use the interceptor.
<span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="interceptors"</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">list</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">ref </span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="handlerInterceptor1"</span><span style="color: #0000ff">/></span> <span style="color: #0000ff"><</span><span style="color: #800000">ref </span><span style="color: #ff0000">bean</span><span style="color: #0000ff">="handlerInterceptor2"</span><span style="color: #0000ff">/></span> <span style="color: #0000ff"></</span><span style="color: #800000">list</span><span style="color: #0000ff">></span> <span style="color: #0000ff"></</span><span style="color: #800000">property</span><span style="color: #0000ff">></span> <span style="color: #0000ff"></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">id</span><span style="color: #0000ff">="handlerInterceptor1"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor1"</span><span style="color: #0000ff">/></span> <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">id</span><span style="color: #0000ff">="handlerInterceptor2"</span><span style="color: #ff0000"> class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor2"</span><span style="color: #0000ff">/></span>
Generally not recommended.
springmvc can configure similar global interceptors, and the springmvc framework injects the configured global-like interceptors into each HandlerMapping.
<span style="color: #008000"><!--</span><span style="color: #008000">拦截器 </span><span style="color: #008000">--></span> <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptors</span><span style="color: #0000ff">></span> <span style="color: #008000"><!--</span><span style="color: #008000">多个拦截器,顺序执行 </span><span style="color: #008000">--></span> <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span> <span style="color: #008000"><!--</span><span style="color: #008000"> /**表示所有url包括子url路径 </span><span style="color: #008000">--></span> <span style="color: #0000ff"><</span><span style="color: #800000">mvc:mapping </span><span style="color: #ff0000">path</span><span style="color: #0000ff">="/**"</span><span style="color: #0000ff">/></span> <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor1"</span><span style="color: #0000ff">></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span> <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span> <span style="color: #0000ff"><</span><span style="color: #800000">mvc:mapping </span><span style="color: #ff0000">path</span><span style="color: #0000ff">="/**"</span><span style="color: #0000ff">/></span> <span style="color: #0000ff"><</span><span style="color: #800000">bean </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="joanna.yan.ssm.interceptor.HandlerInterceptor2"</span><span style="color: #0000ff">></</span><span style="color: #800000">bean</span><span style="color: #0000ff">></span> <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptor</span><span style="color: #0000ff">></span> <span style="color: #0000ff"></</span><span style="color: #800000">mvc:interceptors</span><span style="color: #0000ff">></span>
Test the execution timing of each method of multiple interceptors.
Run log information:
<span style="color: #000000">HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle HandlerInterceptor2...postHandle HandlerInterceptor1...postHandle HandlerInterceptor2...afterCompletion HandlerInterceptor1...afterCompletion</span>
Summarize:
The preHandle method is executed in order, and postHandle and afterCompletion are executed in the reverse order of the interceptor configuration.
Run log information:
<span style="color: #000000">HandlerInterceptor1...preHandle HandlerInterceptor2...preHandle HandlerInterceptor1...afterCompletion</span>
Summarize:
Interceptor 1 is released, and the preHandle of interceptor 2 will be executed.
The preHandle of interceptor 2 will not be released, and the postHandle and afterCompletion of interceptor 2 will not be executed.
As long as there is an interceptor that does not release, postHandle will not be executed.
Run log information:
HandlerInterceptor1...preHandle
The preHandle of interceptor 1 is not released, and postHandle and afterCompletion will not be executed.
The preHandle of interceptor 1 is not released, and interceptor 2 is not executed.
Apply the interceptor based on the test results.
For example: Unified log processing interceptor, if the interceptor preHandle needs to be changed, it must be released and placed at the first position in the interceptor chain.
For example: login authentication interceptor, placed at the first position in the interceptor chain. The permission verification interceptor is placed after the login interceptor. (Because the permissions are verified after the login is passed)
(1) User request url
(2) Interceptor performs interception verification
If the requested URL is a public address (a URL that can be accessed without logging in), let it pass
If the user session does not exist, jump to the login page.
If the user session exists, release it and continue the operation.
<span style="color: #0000ff">package</span><span style="color: #000000"> joanna.yan.ssm.controller; </span><span style="color: #0000ff">import</span><span style="color: #000000"> javax.servlet.http.HttpSession; </span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.stereotype.Controller; </span><span style="color: #0000ff">import</span><span style="color: #000000"> org.springframework.web.bind.annotation.RequestMapping; @Controller </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> LoginController { </span><span style="color: #008000">//</span><span style="color: #008000">登录</span> @RequestMapping("/login"<span style="color: #000000">) </span><span style="color: #0000ff">public</span> String login(HttpSession session, String username, String password) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception{ </span><span style="color: #008000">//</span><span style="color: #008000">调用service进行用户身份认证 </span><span style="color: #008000">//</span><span style="color: #008000">... </span><span style="color: #008000">//</span><span style="color: #008000">在session中保存用户身份信息</span> session.setAttribute("username"<span style="color: #000000">, username); </span><span style="color: #0000ff">return</span> "redirect:items/queryItems.action"<span style="color: #000000">; } </span><span style="color: #008000">//</span><span style="color: #008000">退出</span> @RequestMapping("/logout"<span style="color: #000000">) </span><span style="color: #0000ff">public</span> String logout(HttpSession session) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception{ </span><span style="color: #008000">//</span><span style="color: #008000">清除session</span> <span style="color: #000000"> session.invalidate(); </span><span style="color: #0000ff">return</span> "redirect:items/queryItems.action"<span style="color: #000000">; } }</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> LoginInterceptor <span style="color: #0000ff">implements</span><span style="color: #000000"> HandlerInterceptor{ </span><span style="color: #008000">//</span><span style="color: #008000">执行Handler完成执行此方法 </span><span style="color: #008000">//</span><span style="color: #008000">应用场景:统一异常处理,统一日志处理</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......afterCompletion"<span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之后,返回modelAndView之前执行 </span><span style="color: #008000">//</span><span style="color: #008000">应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里同意指定视图</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......postHandle"<span style="color: #000000">); } </span><span style="color: #008000">//</span><span style="color: #008000">进入Handler方法之前执行 </span><span style="color: #008000">//</span><span style="color: #008000">用于身份认证、身份授权 </span><span style="color: #008000">//</span><span style="color: #008000">比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不再向下执行。</span> <span style="color: #000000"> @Override </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) </span><span style="color: #0000ff">throws</span><span style="color: #000000"> Exception { System.out.println(</span>"HandlerInterceptor1......preHandle"<span style="color: #000000">); </span><span style="color: #008000">//</span><span style="color: #008000">获取请求的url</span> String url=<span style="color: #000000">request.getRequestURI(); </span><span style="color: #008000">//</span><span style="color: #008000">判断url是否是公开地址(实际使用时要将公开地址配置到文件中) </span><span style="color: #008000">//</span><span style="color: #008000">这里公开地址是登录提交的地址</span> <span style="color: #0000ff">if</span>(url.indexOf("login.action")>=0<span style="color: #000000">){ </span><span style="color: #008000">//</span><span style="color: #008000">如果进行登录提交,放行</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; } </span><span style="color: #008000">//</span><span style="color: #008000">判断session</span> HttpSession session=<span style="color: #000000">request.getSession(); String username</span>=(String) session.getAttribute("username"<span style="color: #000000">); </span><span style="color: #0000ff">if</span>(username!=<span style="color: #0000ff">null</span><span style="color: #000000">){ </span><span style="color: #008000">//</span><span style="color: #008000">身份存在,放行</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; } </span><span style="color: #008000">//</span><span style="color: #008000">执行到这里,表示用户身份需要认证,跳转登录页面</span> request.getRequestDispatcher("/WEB-INF/jsp/login.jsp"<span style="color: #000000">).forward(request, response); </span><span style="color: #008000">//</span><span style="color: #008000">return false表示拦截,不向下执行 </span><span style="color: #008000">//</span><span style="color: #008000">return true表示放行</span> <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; } }</span>
Configuration in springmvc.xml under classpath:
If this article is helpful to you, please tip me on WeChat~
The above is the detailed content of Spring+SpringMVC+MyBatis in-depth learning and construction (17) - SpringMVC interceptor. For more information, please follow other related articles on the PHP Chinese website!