当前位置:首页 » 《随便一记》 » 正文

【Java Web】过滤器及其配置 过滤器链 (含代码示例)

23 人参与  2025年01月01日 08:02  分类 : 《随便一记》  评论

点击全文阅读


文章目录

过滤器配置文件配置注解配置 代码示例过滤器链
过滤器是一种用于对请求和响应进行预处理和后处理的组件。它可以拦截客户端发往服务器的请求以及服务器返回给客户端的响应,在这个过程中对数据进行特定的操作,比如:

验证和授权:检查用户是否具有访问特定资源的权限,例如验证用户登录状态、检查用户是否属于特定角色等,只有通过验证的请求才被允许继续传递到目标资源(如 Servlet 或 JSP 页面等)。数据过滤和转换:对请求中的数据进行过滤,去除非法或不符合要求的数据,或者对数据进行格式转换。例如,将输入的字符串中的所有大写字母转换为小写字母后再传递给后续处理环节,或者过滤掉包含特定敏感词汇的内容。日志记录:记录请求和响应的相关信息,如请求的 URL、请求时间、响应状态码等,以便于后续的监控和分析,了解应用程序的使用情况和性能表现。性能优化:通过缓存经常访问的资源或者对请求进行压缩等操作来提高应用程序的整体性能。

在这里插入图片描述

过滤器配置

文件配置

web.xml 中定义过滤器,使用<filter>标签及其子标签。如果过滤器需要一些初始化参数来进行工作,可以在<filter>标签内添加<init-param>子标签来配置,类似于 Servlet 的初始化参数配置方式。

<filter>    <!-- 过滤器的名称,可自定义,用于在web.xml内部标识该过滤器 -->    <filter-name>MyFilter</filter-name>    <!-- 过滤器的完整类名,包括包名 -->    <filter-class>com.example.MyFilterClass</filter-class>        <!-- 开始配置初始化参数 -->    <init-param>        <!-- 参数名称,可自定义 -->        <param-name>configKey</param-name>        <!-- 参数值,根据实际需求设置 -->        <param-value>configValue</param-value>    </init-param>    <init-param>        <param-name>anotherParamKey</param-value>        <param-value>anotherParamValue</param-value>    </init-param>    <!-- 结束配置初始化参数 -->    </filter>

定义好过滤器后,需要将其与特定的资源或请求进行映射,以确定哪些请求会被该过滤器拦截。通过<filter-mapping>标签

<filter-mapping>    <!-- 这里的filter-name要和前面定义过滤器时设置的名称一致 -->    <filter-name>MyFilter</filter-name>    <!-- 定义该过滤器拦截的URL模式,可以是精确匹配的具体URL,也可以是精确匹配的资源类型,或者通配符模式 -->    <url-pattern>/myFilterPath/*</url-pattern></filter-mapping>
完全匹配:/index.jsp目录匹配:/admin/*扩展名匹配:*.do全部匹配:/*

除了通过 URL 模式进行映射外,还可以通过指定资源类型(如 Servlet、JSP 等)来进行映射

<filter-mapping>    <filter-name>MyFilter</filter-name>    <filter-class>com.example.MyFilterClass</filter-class>    <!-- 指定要拦截的资源类型为Servlet -->    <servlet-name>MyServlet</servlet-name></filter-mapping>

在上述示例中,通过<servlet-name>标签指定了要拦截的特定 Servlet(这里假设之前已经在web.xml中定义了MyServlet),即当请求指向MyServlet时,MyFilter过滤器会对该请求进行拦截处理。

注解配置

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface WebFilter {    String description() default "";    String displayName() default "";    WebInitParam[] initParams() default {};    String filterName() default "";    String smallIcon() default "";    String largeIcon() default "";    String[] servletNames() default {};    String[] value() default {};    String[] urlPatterns() default {};    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};    boolean asyncSupported() default false;}

基本用法

urlPatterns:定义过滤器需要拦截的URL模式,可以是一个或多个模式。servletNames:如果过滤器只应用于特定的Servlet,可以通过此属性指定Servlet名称。filterName:过滤器的名字。initParams:初始化参数,可以通过InitParam注解来定义。dispatcherTypes:指明过滤器作用于哪个分派类型,例如REQUEST, FORWARD, INCLUDE, ERROR等,默认是REQUEST。asyncSupported:是否支持异步处理,默认值为false。
@WebFilter(urlPatterns = {"/secure/*"}, filterName = "loginCheckFilter",           initParams = {@WebInitParam(name = "param1", value = "value1")})

代码示例

创建一个实现 javax.servlet.Filter 接口的 Java 类。重写 init()doFilter()destroy() 方法,这个类将定义过滤器的具体行为。

public class MyFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {           }    @Override    public void destroy() {    }}

完成上述步骤后,将 Web 应用部署到 Apache Tomcat 中,然后通过浏览器或其他客户端工具发送符合过滤器拦截条件的请求,观察过滤器的执行情况,看是否按照预期对请求和响应进行了处理。

实现一个字符编码过滤器,设置请求和响应的字符编码。

@WebFilter("/*")public class CharEncodingFilter implements Filter {    private String charSetContent = "GBK";    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // 获取全局配置参数        charSetContent = filterConfig.getServletContext().getInitParameter("charSetContent");    }    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) servletRequest;        HttpServletResponse response = (HttpServletResponse) servletResponse;        request.setCharacterEncoding(charSetContent);        response.setCharacterEncoding(charSetContent);        // 放行        filterChain.doFilter(servletRequest,servletResponse);    }    @Override    public void destroy() {}}

实现一个登录检查过滤器,检查用户是否已登录。

@WebFilter("/servlet/*")public class LoginServlet implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {}    @Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) servletRequest;        HttpServletResponse response = (HttpServletResponse) servletResponse;        if (request.getSession().getAttribute("smbmsUser") == null) {            response.sendRedirect("/login.jsp");        } else {            filterChain.doFilter(servletRequest, servletResponse);        }    }    @Override    public void destroy() {}}

过滤器链

多个过滤器按照特定的顺序依次对客户端发往服务器的请求以及服务器返回给客户端的响应进行处理所形成的链条状结构。

web.xml 文件中配置过滤器时,过滤器的映射顺序决定了它们在过滤器链中的处理顺序。

<filter>    <filter-name>FilterA</filter-name>    <filter-class>com.example.FilterAClass</filter-class></filter><filter-mapping>    <filter-name>FilterA</filter-name>    <url-pattern>/somePath/*</url-pattern></filter-mapping><filter>    <filter-name>FilterB</filter-name>    <filter-class>com.example.FilterBClass</filter-class></filter><filter-mapping>    <filter-name>FilterB</filter-name>    <url-ppatter>/somePath/*</url-pattern></filter-mapping>

上述配置中,由于 FilterA 的配置在 FilterB 之前,所以在处理请求时,FilterA 会先对请求进行处理,然后将请求传递给 FilterB;在处理响应时,FilterB 会先对响应进行处理,然后将响应传递给 FilterA。


点击全文阅读


本文链接:http://zhangshiyu.com/post/210048.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1