标签:
Spring Web MVC的处理器拦截器(如无特殊说明,下文所说的拦截器即处理器拦截器)类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
常见应用场景如下:
本质是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。
SpringMVC中拦截器接口是HandleInterceptor,源码如下:
package org.springframework.web.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.method.HandlerMethod; public interface HandlerInterceptor { /** * @param request current HTTP request * @param response current HTTP response * @param handler chosen handler to execute, for type and/or instance evaluation * @return {@code true} if the execution chain should proceed with the * @throws Exception in case of errors */ boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; /** * Intercept the execution of a handler. Called after HandlerAdapter actually * @param request current HTTP request * @param response current HTTP response * @param handler handler (or {@link HandlerMethod}) that started async * execution, for type and/or instance examination * @param modelAndView the {@code ModelAndView} that the handler returned * @throws Exception in case of errors */ void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; /** * Callback after completion of request processing, that is, after rendering * @param request current HTTP request * @param response current HTTP response * @param handler handler (or {@link HandlerMethod}) that started async * execution, for type and/or instance examination * @param ex exception thrown on handler execution, if any * @throws Exception in case of errors */ void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如Controller实现);返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
如果使用接口实现的方式,我们要实现三个方法,HandlerInterceptorAdapter 提供了方便,它是HandlerInterceptor的一个抽象实现,源码如下:
package org.springframework.web.servlet.handler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.AsyncHandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * Abstract adapter class for the HandlerInterceptor interface, * for simplified implementation of pre-only/post-only interceptors. * * @author Juergen Hoeller * @since 05.12.2003 */ public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { /** * This implementation always returns {@code true}. */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } /** * This implementation is empty. */ @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * This implementation is empty. */ @Override public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } /** * This implementation is empty. */ @Override public void afterConcurrentHandlingStarted( HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { } }
使用SpringMVC拦截器是否登录,未登录用户跳转至登录页面。
创建拦截器(实现接口)
package com.ywlaker.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import com.ywlaker.constant.ConstantSession; import com.ywlaker.tools.ToolString; public class LoginInterceptor implements HandlerInterceptor{ @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { } @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { } @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception { //不拦截登录请求 String path = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort(); String url = req.getRequestURI(); String[] urls = {"/admin","/admin/login","/admin/login/check","/admin/logout"}; if (ToolString.isIncluded(url, urls)) return true; //已经登录的放行 HttpSession session = req.getSession(); Object admin = session.getAttribute(ConstantSession.SESSION_ADMIN); if (admin != null) return true; //非法请求跳转至登录 res.sendRedirect(path + "/admin"); return false; } }
创建拦截器(继承适配器)
package com.ywlaker.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.ywlaker.constant.ConstantSession; import com.ywlaker.tools.ToolString; public class LoginInterceptor extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception { //不拦截登录请求 String path = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort(); String url = req.getRequestURI(); String[] urls = {"/admin","/admin/login","/admin/login/check","/admin/logout"}; if (ToolString.isIncluded(url, urls)) return true; //已经登录的放行 HttpSession session = req.getSession(); Object admin = session.getAttribute(ConstantSession.SESSION_ADMIN); if (admin != null) return true; //非法请求跳转至登录 res.sendRedirect(path + "/admin"); return false; } }
配置SpringMVC拦截器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <!-- 登录拦截器配置 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path=""/> <mvc:exclude-mapping path="/admin"/> <bean class="com.ywlaker.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> </beans>
标签:
原文地址:http://www.cnblogs.com/ywlaker/p/4729977.html