一:拦截器的应用场景
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page VIEW)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开SESSION,在完成后关闭SESSION。
二:拦截器与过滤器的区别
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3、拦截器只能对ACTION请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问ACTION上下文、值栈里的对象,而过滤器不能访问。
5、在ACTION的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
三:拦截器的实现
1.过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在chain.doFilter(request, response);这个方法中进行的。
2.拦截器是被包裹在过滤器之中的。
a.preHandle()这个方法是在过滤器的chain.doFilter(request, response)方法的前一步执行,也就是在 [System.out.println("before...")][chain.doFilter(request, response)]之间执行。
b.preHandle()方法之后,在RETURN ModelAndView之前进行,可以操控Controller的ModelAndView内容。
c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之间执行。
四:SpringMvc 拦截器和过滤器执行流程
五:实例
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page VIEW)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开SESSION,在完成后关闭SESSION。
二:拦截器与过滤器的区别
1、拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
2、拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3、拦截器只能对ACTION请求起作用,而过滤器则可以对几乎所有的请求起作用。
4、拦截器可以访问ACTION上下文、值栈里的对象,而过滤器不能访问。
5、在ACTION的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
6、拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
三:拦截器的实现
1.过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
点击(此处)折叠或打开
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
- System.out.println("before...");
- chain.doFilter(request, response);
- System.out.println("after...");
- }
2.拦截器是被包裹在过滤器之中的。
点击(此处)折叠或打开
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- System.out.println("preHandle");
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("afterCompletion");
- }
b.preHandle()方法之后,在RETURN ModelAndView之前进行,可以操控Controller的ModelAndView内容。
c.afterCompletion()方法是在过滤器返回给前端前一步执行,也就是在[chain.doFilter(request, response)][System.out.println("after...")]之间执行。
四:SpringMvc 拦截器和过滤器执行流程
五:实例
点击(此处)折叠或打开
- public class SystemAccessInterceper extends HandlerInterceptorAdapter {
-
- private final String checkpointName = "DO_CHECKPOINT";
- private final String shareType = "enjoylink_share";
- String[] noFilters = ConfigureUtil.getStringArray("nofilter.urls");
-
- private final Logger logger = Logger.getLogger(getClass());
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- throws Exception {
- String userAgent = request.getHeader("user-agent");
- userAgent = StringUtils.startsWith(userAgent, Constants.USER_AGENT) ? userAgent
- : request.getHeader("x-user-agent");
- String type = request.getParameter("shareType");
- String requestUri = request.getRequestURI();
- if (isFilter(requestUri)) {
- return true;
- }
- logger.info("User-Agent:" + userAgent);
- if (!StringUtils.equalsIgnoreCase(shareType, type) && (!StringUtils.startsWith(userAgent, Constants.USER_AGENT)
- || 2 > StringUtils.indexOfAny(userAgent, "|"))) {
- logger.info("非法请求接口!!");
- return false;
- }
-
- try {
- if (StringUtils.contains(userAgent, "|")) {
- String[] agts = userAgent.split("\\|");
- request.setAttribute(Constants.HEAD_SYS, agts[1]);
- request.setAttribute(Constants.HEAD_VERSION, agts[2]);
- }
- request.setAttribute(Constants.LOG_ACCESS_TIME, System.currentTimeMillis());
- return super.preHandle(request, response, handler);
- }
- catch (Exception e) {
- logger.error("拦截器验证失败!", e);
- return false;
- }
- }
-
- /**
- * TODO: 检查是否需要过滤
- *
- * @param uri
- * @return
- */
- private boolean isFilter(String uri) {
- if (org.apache.commons.lang3.ArrayUtils.isEmpty(noFilters)) {
- return Boolean.TRUE;
- }
-
- for (String noFilter : noFilters) {
- if (StringUtils.contains(uri, noFilter)) {
- return Boolean.TRUE;
- }
- }
-
- return Boolean.FALSE;
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- super.afterCompletion(request, response, handler, ex);
- Object obj = request.getAttribute(Constants.LOG_ACCESS_TIME);
- if (null != obj) {
- Object rb = request.getAttribute(Constants.RETURN_BODY);
- long accessTime = (long) obj;
- if (null == rb || StringUtils.isEmpty(rb.toString())) {
- logger.info("不进行检查点处理!");
- logger.info("处理请求" + request.getRequestURI() +"耗时"+ (System.currentTimeMillis() - accessTime) + "毫秒!");
- return;
- }
- Object userId = request.getAttribute(Constants.REQUEST_USERID);
- String system = request.getAttribute(Constants.HEAD_SYS).toString();
- String version = request.getAttribute(Constants.HEAD_VERSION).toString();
-
- logger.warn("处理请求|" + ((null == userId || "".equals(userId.toString())) ? "0" : userId.toString()) + "|"
- + system + "|" + version + "|" + request.getRequestURI() + "|"
- + GbdDateUtils.format(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm:ss") + "|"
- + (System.currentTimeMillis() - accessTime) + "|毫秒!");
- try {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- BusinessCheckPoint checkPoint = handlerMethod.getMethodAnnotation(BusinessCheckPoint.class);
- if (null != checkPoint) {
- String checkpointKey = checkPoint.checkName();
-
- // 业务处理结果为正确时。发送积分或者信用累积
- if (null != rb && null != userId && StringUtils.isNotEmpty(userId.toString())) {
- ReturnBody returnBody = (ReturnBody) rb;
- // 检查点检测,如果是检查点则发送消息
- if (returnBody.getCode() > 0) {
- // 发送检查点消息
- CodeDesc codeDesc = new CodeDesc();
- codeDesc.setJmsType(checkpointName);
- codeDesc.setName(checkpointKey);
- codeDesc.setBusinessCode(returnBody.getCheckpointCode());
- codeDesc.setUserId(Integer.valueOf(userId.toString()));
- JmsUtil.pushToUserQueue(codeDesc);
- }
- }
- }
- }
- catch (Exception e) {
- logger.error("发送积分消息失败!", e);
- }
- }
- }
-
- }
点击(此处)折叠或打开
- <!-- 拦截器配置 -->
- <mvc:interceptors>
- <bean class="com.gemdale.ghome.business.intercepter.SystemAccessInterceper" />
- </mvc:interceptors>
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28624388/viewspace-2130071/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/28624388/viewspace-2130071/