前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Filter过滤器

Filter过滤器

作者头像
Breeze.
发布2022-07-12 15:00:44
4580
发布2022-07-12 15:00:44
举报
文章被收录于专栏:一只无聊的清风

过滤器

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

过滤链

image-20220710182705027
image-20220710182705027

Filter开发

开发过滤器三要素:

  1. 任何过滤器都要实现 javax.servlet.Filter 接口
  2. 在Filter接口的doFilter()方法中编写过滤器的功能代码
代码语言:javascript
复制
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的范围
代码语言:javascript
复制
    <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
image-20220710193102125
过滤器的特性

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

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

Filter应用实践

WebFilter注解使用

代码语言:javascript
复制
@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”)
代码语言:javascript
复制
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>设置过滤器参数

代码语言:javascript
复制
<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>
代码语言:javascript
复制
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
image-20220711005917038

多参数,添加多次init-param

注解形式
代码语言:javascript
复制
@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
image-20220710182705027
  • 每一个过滤器应具有单独职能
  • 过滤器的执行顺序以<filter-mapping>为准
  • 调用chain.doFilter()将请求向后传递

多端设备自动匹配

代码语言:javascript
复制
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对象行为监听,是被动触发

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 过滤器
    • 过滤链
    • Filter开发
      • 过滤器声明周期
        • 过滤器的特性
    • Filter应用实践
      • WebFilter注解使用
        • 配置与注解如何选择
          • 字符集过滤器
            • 参数化过滤器
              • 注解形式
            • url-pattern常用写法
              • /与/*的区别
                • 过滤链
                  • 多端设备自动匹配
                  • 监听器-Listener
                    • 过滤器与监听器的区别
                    相关产品与服务
                    项目管理
                    CODING 项目管理(CODING Project Management,CODING-PM)工具包含迭代管理、需求管理、任务管理、缺陷管理、文件/wiki 等功能,适用于研发团队进行项目管理或敏捷开发实践。结合敏捷研发理念,帮助您对产品进行迭代规划,让每个迭代中的需求、任务、缺陷无障碍沟通流转, 让项目开发过程风险可控,达到可持续性快速迭代。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档