Spring Interceptor vs Filter

栏目: Java · 发布时间: 5年前

内容简介:Filter,顾名思义,过滤器,是由servlet容器为每个传入的http请求和每个http响应执行的Java类。 这样,就可以在HTTP传入请求到达资源之前对其进行管理,例如JSP页面,servlet或简单的静态页面; 以相同的方式可以在资源执行后管理HTTP出站响应。此行为允许实现在许多不同上下文中重用的常用功能。如上图所示,过滤器在Web容器中运行,因此其定义也将包含在web.xml文件中。

Filter,顾名思义,过滤器,是由servlet容器为每个传入的http请求和每个http响应执行的 Java 类。 这样,就可以在HTTP传入请求到达资源之前对其进行管理,例如JSP页面,servlet或简单的静态页面; 以相同的方式可以在资源执行后管理HTTP出站响应。

此行为允许实现在许多不同上下文中重用的常用功能。

Spring Interceptor vs Filter

如上图所示,过滤器在Web容器中运行,因此其定义也将包含在web.xml文件中。

<filter>
    <filter-name>CORSFilter</filter-name>
    <filter-class>com.listfeeds.components.CORSFilter</filter-class>
    <init-param>
        <param-name>fake-param</param-name>
        <param-value>fake-param-value</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
复制代码

在过滤器定义中,由com.listfeeds.filters.CORSFilter类实现的过滤器具有满足表达式的所有端点:/ *(在本例中为all)

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

public class CORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}
复制代码

Filter包括三个主要方法:

  • init:执行以使用过滤器定义中的init-param元素初始化过滤器
  • doFilter:为满足“url-pattern”的所有HTTP传入请求执行
  • 释放过滤器使用的资源

Interceptor

Spring拦截器类似于Servlet过滤器,但它们在Spring Context中起作用,因此管理HTTP请求和响应的功能非常强大,但它们可以实现更加软化的行为,因为它可以访问所有Spring上下文。

Spring Interceptor vs Filter

Spring拦截器在SpringMVC上下文中执行,因此它们已在spring-servlet.xml文件中定义:

<mvc:interceptors>
    <bean class="com.listfeeds.interceptors.LogContextInterceptor" />
    <bean class="com.listfeeds.interceptors.TimedInterceptor" />
</mvc:interceptors>
复制代码

com.listfeeds.interceptors.LogContextInterceptor拦截器类,用于向Log4j Thread上下文添加参数。

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.MDC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LogContextInterceptor extends HandlerInterceptorAdapter {

    private static final Logger log = LoggerFactory.getLogger(LogContextInterceptor.class);

    public static final String LOG_IDENTIFYING_TOKEN = "logIdentifyingToken";

    @Override
    public void afterCompletion(
            HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

        HandlerMethod methodHandler = (HandlerMethod) handler;
        log.debug("END EXECUTION method {} request: {}", methodHandler.getMethod().getName(), request.getRequestURI());

        Boolean settato = (Boolean) request.getAttribute(LOG_IDENTIFYING_TOKEN);
        if(settato != null && settato) {
            MDC.remove(LOG_IDENTIFYING_TOKEN);
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {

        try {
            if( MDC.get(LOG_IDENTIFYING_TOKEN) == null ) {

                /* Retrieve parameters useful for logging */
                @SuppressWarnings("unchecked")
                Map<String,String> pathVariables = 
                (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);

                String applicationId = null;
                if ( pathVariables != null ) 
                    applicationId = pathVariables.get("applicationId");

                if ( StringUtils.isEmpty(applicationId) ) 
                    applicationId = request.getParameter("applicationId");

                String loggingToken = 
                        String.format("ApplicationId: %s", applicationId);

                MDC.put(LOG_IDENTIFYING_TOKEN, loggingToken);
                request.setAttribute(LOG_IDENTIFYING_TOKEN, Boolean.TRUE);
            }


        }
        catch ( IllegalArgumentException e)
        {
            log.warn("Prehandle",e);
            return true;
        }
        finally {
            HandlerMethod methodHandler = (HandlerMethod) handler;
            //logger.debug("START EXECUTION " + methodHandler.getMethod().getName());
            log.debug("START EXECUTION method {} request: {}", methodHandler.getMethod().getName(), request.getRequestURI());


        }


        return true;
    }

}
复制代码

interceptor 包含如下几个主要方法:

  • preHandle:在执行目标资源之前执行
  • afterCompletion:执行目标资源后执行(渲染视图后)
  • posttHandle:拦截处理程序的执行

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

编写高质量代码

编写高质量代码

秦小波 / 机械工业出版社华章公司 / 2011-12-28 / 59.00元

在通往“Java技术殿堂”的路上,本书将为你指点迷津!内容全部由Java编码的最佳实践组成,从语法、程序设计和架构、工具和框架、编码风格和编程思想等五大方面对Java程序员遇到的各种棘手的疑难问题给出了经验性的解决方案,为Java程序员如何编写高质量的Java代码提出了151条极为宝贵的建议。对于每一个问题,不仅以建议的方式从正反两面给出了被实践证明为十分优秀的解决方案和非常糟糕的解决方案,而且还......一起来看看 《编写高质量代码》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具