过滤器 – Filter

内容纲要
  • 过滤器(Filter) 是J2EE Servlet模块下的组件
  • Filter的作用是对URL进行统一的拦截处理
  • Filter通常用于应用程序层面进行全局处理

开发过滤器的三要素

  • 任何过滤器都要实现javax.servlet.Filter接口
  • 在Filter接口的doFilter()方法中编写过滤器的功能代码
  • 在web.xmI中对过滤器进行配置,说明拦截URL的范围
<!-- filter标签用于说明哪个类是过滤器,并在应用启动时自动加载-->
<filter>
    <filter-name>MyFistFilter</filter-name>
    <filter-class>fun.afterglow.filter.MyFilter</filter-class>
</filter>
<!--
    filter -mapping标签用于说明过滤器对URL应用的范围,要点有二:
    1. filter-name 过滤器名称与filter. filter-name保持- -致
    2. url- pattern说明过滤器作用范围,/*代表对所有URL进行过滤
-->
<filter-mapping>
    <filter-name>MyFistFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器的生命周期

过滤器的特征

  • 过滤器对象在Web应用启动时被创建且全局唯一
  • 唯一的过滤器对象在并发环境中采用“多线程”提供服务

    过滤器的两种开发方式

    过滤器的配置形式

<filter>
    <filter-name>MyFistFilter</filter-name>
    <filter-class>fun.afterglow.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFistFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器注解形式

@WebFilter (filterName= "MyAnnoationFilter",urlPatterns= "/*")
public class MyAnnotationFilter implements Filter {

配置与注解如何选择

  • 最好只选择种方式进行开发
  • 配置形式维护性更好,适合应用全局过滤,中大型项目开发
  • 注解形式开发体验更好,适用于小型项目敏捷开发个人项目开发

    开发字符集过滤器

    Web中文乱码的解决

  • GET请求- server.xml增加URIEncoding="UTF-8"
  • POST请求-使用request.setCharacterEncoding("UTF-8");
  • 响应-response.setContentType("text/html; charset=UTF-8")
@WebFilter(filterName = "cahracterEncodingEilter",urlPatterns = "/*")
public class cahracterEncodingEilter 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;
        request.setCharacterEncoding("UTF-8");
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        response.setContentType("text/html;charset=UTF-8");
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
    }
}

ServletRequest接口

过滤器参数化

  • 过滤器为了增强灵活性,允许配置信息放在web.xml
  • 在web.xmI中配置设置过滤器参数

优化字符集过滤器

  • 配置法
<filter>
    <filter-name>cahracterEncodingEilter</filter-name>
    <filter-class>fun.afterglow.filter.cahracterEncodingEilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>cahracterEncodingEilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
@WebFilter(filterName = "cahracterEncodingEilter",urlPatterns = "/*")
public class cahracterEncodingEilter implements Filter {
    private String encoding;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encoding=filterConfig.getInitParameter("encoding");
        System.out.println(encoding);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        request.setCharacterEncoding(encoding);
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        response.setContentType("text/html;charset="+encoding);
        filterChain.doFilter(servletRequest,servletResponse);
    }
    @Override
    public void destroy() {
    }
}
  • 注解法
@WebFilter(filterName = "cahracterEncodingEilter", urlPatterns = "/*",
        initParams = {
                @WebInitParam(name = "encoding",value = "UTF-8"),
                @WebInitParam(name = "p1",value = "v1"),
                @WebInitParam(name = "p2",value = "v2"),
})
public class cahracterEncodingEilter implements Filter {
    private String encoding;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encoding = filterConfig.getInitParameter("encoding");
        System.out.println(encoding);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        request.setCharacterEncoding(encoding);
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setContentType("text/html;charset=" + encoding);
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {
    }
}

url-pattern设置过滤范围

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

    /映射的问题

  • /指映射Web应用根路径,且只对Servlet生效
  • 默认首页index.jsp会让/失效
  • /与/*含义不同,前者指向根路径,后者代表所有

    过滤链

    过滤链开发注意事项

  • 每一个过滤器应具有单独职能
  • 过滤器的执行顺序以< filter-mapping>为准
  • 使用注解的方式配置是通过类名排序规则配置的
  • 调用chain.doFilter()将请求向后传递

    多端设备自动匹配

public class DeviceAdapterFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        /*
         /index.html
         PC: /desktop/index.html
         MOBILE: /mobile/index.html
         /test.html
         PC: /desktop/test.html
         MOBILE: /mobile/test.html
         */
        String uri = req.getRequestURI();
        System.out.println("URI:" + uri);
        if (uri.startsWith("/desktop") || uri.startsWith("/mobile")) {
            chain.doFilter(request, response);
        } else {
            //获取user-agent并将所有字符串转为小写
            String userAgent = req.getHeader("user-agent").toLowerCase();
            String targetURI = "";
            //判断当前设备是否为手机端设备
            if (userAgent.indexOf("android") != -1 || userAgent.indexOf("iphone") != -1) {
                targetURI = "/mobile" + uri;
                System.out.println("移动端设备正在访问,重新跳转到URI:" + targetURI);
                res.sendRedirect(targetURI);
            } else {
                targetURI = "/desktop" + uri;
                System.out.println("PC端设备正在访问,重新跳转到URI:" + targetURI);
                res.sendRedirect(targetURI);
            }
        }
    }
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
}
THE END
分享
二维码
< <上一篇
下一篇>>