Javaweb中的过滤器

  • 在 JavaWeb 中,过滤器(Filter)是一种用于在 Servlet 容器中对请求和响应进行预处理和后处理的组件。
  • 过滤器是 JavaEE 规范的一部分,用于在请求到达 Servlet 之前或 Servlet 响应返回客户端之前执行一些操作。
  • 过滤器主要用于在请求处理前或响应生成后修改请求或响应的内容,例如修改请求参数、设置字符编码、身份验证、日志记录等。
  • 过滤器的工作原理是基于责任链模式,它可以串联多个过滤器,形成一个过滤器链。
  • 每个过滤器都可以对请求进行处理,然后将请求传递给下一个过滤器。这样的过滤器链可以在请求到达 Servlet 之前或响应返回客户端之前执行一系列的操作。

以下是一个简单的过滤器的示例,用于设置字符编码:

java

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 java.io.IOException;

public class CharsetFilter implements Filter {
    private String encoding;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 从配置文件获取字符编码设置
        encoding = filterConfig.getInitParameter("encoding");
        if (encoding == null) {
            encoding = "UTF-8"; // 默认使用 UTF-8
        }
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 在请求到达 Servlet 之前执行的操作
        request.setCharacterEncoding(encoding);

        // 执行下一个过滤器,如果没有过滤器了,则执行目标 Servlet
        chain.doFilter(request, response);

        // 在响应返回给客户端之前执行的操作
        // 这里可以对响应进行一些操作,如设置响应头、添加响应内容等
    }

    @Override
    public void destroy() {
        // 过滤器销毁操作
    }
}

在上述示例中,CharsetFilter 过滤器用于设置请求的字符编码,在 doFilter 方法中,它调用了 request.setCharacterEncoding(encoding) 来设置请求的字符编码。这样,在请求到达 Servlet 之前,字符编码已经被正确设置。

要在 JavaWeb 中使用过滤器,需要在 web.xml 配置文件中声明过滤器,并将其映射到相应的 URL 模式

xml

<filter>
    <filter-name>CharsetFilter</filter-name>
    <filter-class>com.example.CharsetFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharsetFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这样,CharsetFilter 就会对所有的请求进行字符编码的设置。 这只是过滤器的一种简单应用,实际上,过滤器可以处理更复杂的逻辑,如身份验证、日志记录、性能监控等。

Spring拦截器

  • Spring 拦截器(Interceptor)Spring 框架中用于对请求进行拦截和处理的组件。
  • 拦截器是一种 AOP(面向切面编程)的实现,它允许在请求到达 Controller 之前或 Controller 返回响应之后执行一些操作。
  • 拦截器主要用于对请求进行预处理或对响应进行后处理常见的应用场景包括身份验证、日志记录、性能监控等。
  • 在 Spring MVC 中,拦截器是通过实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter 类来创建的。
  • HandlerInterceptor 接口定义了三个方法,分别在请求处理前、请求处理后、视图渲染完成后执行。
  • 具体的拦截器可以选择实现这些方法中的一部分或全部,根据业务需求进行定制。

以下是一个简单的 Spring 拦截器的示例:

java

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在请求到达 Controller 之前执行的操作
        System.out.println("Interceptor: Pre-handle");

        return true; // 返回 true 表示继续执行后续操作,返回 false 将中断执行链
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在 Controller 返回响应之后,渲染视图之前执行的操作
        System.out.println("Interceptor: Post-handle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        // 在视图渲染完成后执行的操作
        System.out.println("Interceptor: After-completion");
    }
}

上述拦截器实现了 HandlerInterceptor 接口,其中 preHandle 方法在请求到达 Controller 之前执行,postHandle 方法在 Controller 返回响应之后执行,afterCompletion 方法在视图渲染完成后执行。

要在 Spring MVC 中启用拦截器,需要在 Spring 配置文件(通常是 applicationContext.xml 或 WebConfig.java)中进行配置,将拦截器添加到拦截器链中。 以下是一个简单的配置示例:

java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 将自定义拦截器添加到拦截器链中
        registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
    }
}

在上述配置中,addInterceptors 方法将自定义的拦截器添加到拦截器链中,并指定了拦截的路径。这样,拦截器就会对匹配的路径进行拦截。

区别

  • 在 JavaWeb 中,过滤器(Filter)和拦截器(Interceptor)都是用于对请求进行预处理或后处理的组件,它们可以在请求到达 Servlet 或 Controller 之前进行操作,也可以在响应返回给客户端之前进行操作。
  • 虽然它们的作用相似,但它们是两个不同的概念,主要存在于不同的框架中。

过滤器(Filter)

定义: 过滤器是 JavaEE 规范中的一部分,它是基于 Servlet 规范的,用于在请求被分发到 Servlet 之前或 Servlet 响应返回给客户端之前执行一些操作。

作用: 过滤器的主要作用是对请求进行预处理,对响应进行后处理。例如,可以在过滤器中实现对请求的身份验证、字符编码设置、日志记录等操作。

代码示例:

java

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 java.io.IOException;

public class MyFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        // 过滤器初始化操作
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 在请求到达 Servlet 之前执行的操作
        System.out.println("Filter: Processing request...");

        // 执行下一个过滤器,如果没有过滤器了,则执行目标 Servlet
        chain.doFilter(request, response);

        // 在响应返回给客户端之前执行的操作
        System.out.println("Filter: Processing response...");
    }

    public void destroy() {
        // 过滤器销毁操作
    }
}

拦截器(Interceptor)

定义: 拦截器是在 Spring 框架中的一种组件,用于对请求进行拦截和处理。它是 Spring MVC 框架中的一个重要概念,用于在控制器处理请求之前或之后执行一些操作。

作用: 拦截器的主要作用是在请求到达 Controller 之前或 Controller 返回响应之后执行一些操作。它常被用于身份验证、日志记录、性能监控等场景。

代码示例:

java

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在请求到达 Controller 之前执行的操作
        System.out.println("Interceptor: Pre-handle");

        return true; // 返回 true 表示继续执行后续操作,返回 false 将中断执行链
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        // 在 Controller 返回响应之后,渲染视图之前执行的操作
        System.out.println("Interceptor: Post-handle");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                Exception ex) throws Exception {
        // 在视图渲染完成后执行的操作
        System.out.println("Interceptor: After-completion");
    }
}

区别总结:

来源:过滤器是 JavaEE 规范中的一部分,而拦截器是 Spring 框架中的概念。

作用范围:过滤器可以应用于所有的 Servlet,而拦截器主要用于 Spring MVC 中的 Controller。

执行时机:过滤器在请求到达 Servlet 或响应返回客户端之前执行,而拦截器在请求到达 Controller 之前或 Controller 返回响应之后执行。

使用场景:过滤器更适用于通用的请求预处理操作,而拦截器更适用于与具体业务逻辑相关的处理。