Filter过滤器



过滤器

过滤器(Filter)是J2EE Servlet模块下的组件,作用是对URI进行统一拦截处理。Filter通常用于应用程序层面进行请求的前置处理

过滤链

image-20220710182705027

Filter开发

开发过滤器三要素:

  1. 任何过滤器都要实现 javax.servlet.Filter 接口
  2. 在Filter接口的doFilter()方法中编写过滤器的功能代码
public class FirstFilter implements Filter {
    /**
     * 初始化
     *
     * @param filterConfig
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    /**
     * 代码处理核心
     *
     * @param servletRequest  请求
     * @param servletResponse 响应
     * @param filterChain     过滤链
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器已生成");
        // 将请求响应向后传递,被后续的Filter或者Servlet进行处理
        filterChain.doFilter(servletRequest, servletResponse);
    }

    /**
     * 销毁方法
     */
    @Override
    public void destroy() {

    }
}
  1. 在web.xml中对过滤器进行配置,定义拦截URI的范围
    <filter>
        <filter-name>firstFilter</filter-name>
        <filter-class>pers.hua.filter.FirstFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>firstFilter</filter-name>
        <!-- /* 对所有URI进行过滤 -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

过滤器声明周期

会随着服务器启动时进行初始化,服务器关闭或重启是进行销毁。

image-20220710193102125

过滤器的特性

过滤器对象在Web应用启动时被创建且全剧唯一

唯一的过滤器对象在并发环境中采用“多线程”提供服务

Filter应用实践

WebFilter注解使用

@WebFilter(filterName = "annotationFilter", urlPatterns = {"/*"})
public class AnnotationFilter implements Filter {
    ...
}

配置与注解如何选择

  • 配置形式维护性更好,适合应用全局过滤
  • 注解形式开发体验更好,适合小型项目敏捷开发

字符集过滤器

  • GET请求 - servlet.xml 增加URIEncoding=“UTF-8”
  • POST请求 - 使用 request.setCharacterEncoding(“UTF-8”)
  • 响应 - response.setContentType(“text/html;charset=utf-8”)
public class CharacterEncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 设置POST请求字符集
        req.setCharacterEncoding("utf-8");
        // 设置响应体字符集
        resp.setContentType("text/html;charset=UTF-8");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

参数化过滤器

过滤器为了增强灵活性,允许配置信息放在web.xml。在web.xml中配置<init-param>设置过滤器参数

<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>pers.hua.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
public class CharacterEncodingFilter implements Filter {
    private String encoding;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 获取web.xml配置中的init-param名称
        encoding = filterConfig.getInitParameter("encoding");
        System.out.println("Encoding:" + encoding);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 设置POST请求字符集
        req.setCharacterEncoding(encoding);
        // 设置响应体字符集
        resp.setContentType("text/html;charset=" + encoding);
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
image-20220711005917038

多参数,添加多次init-param

注解形式

@WebFilter(filterName = "acef", urlPatterns = "/*",
        initParams = {
                @WebInitParam(name = "encoding", value = "UTF-8"),
                @WebInitParam(name = "name1", value = "value1"),
                @WebInitParam(name = "name2", value = "value2")
        }
)

url-pattern常用写法

  • /index.html - 执行资源精准匹配
  • /servlet/* - 以前缀进行模糊匹配
  • *.html - 以后缀进行模糊匹配

/与/*的区别

/ 应用在Servlet配置,使该Servlet替代主页

/* 应用在过滤器,代表对所有请求拦截

过滤链

image-20220710182705027
  • 每一个过滤器应具有单独职能
  • 过滤器的执行顺序以<filter-mapping>为准
  • 调用chain.doFilter()将请求向后传递

多端设备自动匹配

public class DeviceAdapterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        // 获取URI  移动端:index.html => 自动转为 /mobile/index.html || PC端:index.html => /desktop/index.html
        String uri = req.getRequestURI();
        // 获取请求头
        String userAgent = req.getHeader("User-Agent");
        String targetURL = null;
        // startsWith 当字符串以什么什么开始的时候,做什么后续护理
        if (uri.startsWith("/desktop") || uri.startsWith("/mobile")){
            filterChain.doFilter(servletRequest, servletResponse);
        }else {
            if (userAgent.toLowerCase().indexOf("android") != -1 || userAgent.toLowerCase().indexOf("iphone") != -1) {
                targetURL = "/mobile" + uri;
                System.out.println("移动端正在访问:" + targetURL);
            } else {
                targetURL = "/desktop" + uri;
                System.out.println("PC端正在访问:" + targetURL);
            }
            resp.sendRedirect(targetURL);
        }
    }

    @Override
    public void destroy() {

    }
}

监听器-Listener

监听器(LIstener)是J2EE Servlet模块下的组件,对Web应用对象行为进行监控。通过Listener监听自动除法指定的功能代码

过滤器与监听器的区别

过滤器(Filter)的职责是对URL进行过滤拦截,是主动执行

监听器(Listener)的职责是对Web对象行为监听,是被动触发

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片