2-3-2 Java Web基础-过滤器

过滤器 - Filter介绍

过滤器(Filter)是J2EE Servlet模块下的组件

Filter的作用是对URL进行统一的拦截处理

Filter常用于应用程序层面进行全局处理

开发过滤器的三要素

任何过滤器都要实现javax.servlet.Filter接口

在Filter接口的doFilter()方法中编写过滤器的功能代码

在web.xml中对过滤器进行配置,说明拦截的URL范围

实例

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9  
10 public class MyFirstFilter implements Filter {
11 
12     @Override
13     public void destroy() {
14         // TODO Auto-generated method stub
15         System.out.println("过滤器已被销毁");;
16     }
17 
18     @Override
19     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
20             throws IOException, ServletException {
21         // TODO Auto-generated method stub
22         System.out.println("过滤器已生效");
23         chain.doFilter(request, response);
24     }
25 
26     @Override
27     public void init(FilterConfig filterConfig) throws ServletException {
28         // TODO Auto-generated method stub
29         System.out.println("过滤器初始化成功");
30     }
31 
32 }

web.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>first-filter</display-name>

  <!-- filter标签用于说明哪个类是过滤器,并在应用启动时自动加载 -->
    <filter>
        <filter-name>MyFirstFilter</filter-name>
        <filter-class>com.mingm.filter.MyFirstFilter</filter-class>
    </filter>
    <!-- 
    filter-mapping标签用于说明过滤器对URL应用的范围,要点有二:
    1. filter-name 过滤器名称与filter.filter-name保持一致
    2. url-pattern 说明过滤器作用范围,/* 代表对所有URL进行过滤
    -->
    <filter-mapping>
        <filter-name>MyFirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

过滤器的生命周期

1.初始化 - Filter.init()

2.提供服务 - Filter.doFilter()

3.销毁 - Filter.destory()

过滤器的特性

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

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

过滤器的两种开发方式

过滤器的配置形式

在web.xml配置

  <!-- filter标签用于说明哪个类是过滤器,并在应用启动时自动加载 -->
    <filter>
        <filter-name>MyFirstFilter</filter-name>
        <filter-class>com.imooc.filter.MyFirstFilter</filter-class>
    </filter>
    <!--
    filter-mapping标签用于说明过滤器对URL应用的范围,要点有二:
    1. filter-name 过滤器名称与filter.filter-name保持一致
    2. url-pattern 说明过滤器作用范围,/* 代表对所有URL进行过滤
    -->
    <filter-mapping>
        <filter-name>MyFirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

过滤器的注解形式

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 import javax.servlet.annotation.WebFilter;
10 
11 @WebFilter(filterName="MyAnnotationFilter",urlPatterns="/*")
12 public class MyAnnoationFilter implements Filter{
13 
14     @Override
15     public void destroy() {
16         // TODO Auto-generated method stub
17         
18     }
19 
20     @Override
21     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
22             throws IOException, ServletException {
23         System.out.println("注解形式过滤器已生效");
24         // TODO Auto-generated method stub
25         chain.doFilter(request, response);
26     }
27 
28     @Override
29     public void init(FilterConfig filterConfig) throws ServletException {
30         // TODO Auto-generated method stub
31         
32     }
33 
34 }

配置与注解如何选择

配置维护性更好,适合全局过滤

注解形式开发体验更好,适合小型项目敏捷开发

开发字符过滤器解决Web中文乱码问题

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 import javax.servlet.annotation.WebFilter;
10 import javax.servlet.annotation.WebInitParam;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 @WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*",
14     initParams= {
15             @WebInitParam(name="encoding" , value="GBK"),
16             @WebInitParam(name="p1" , value="v1"),
17             @WebInitParam(name="p2" , value="v2")
18     })
19 public class CharacterEncodingFilter implements Filter {
20     private String encoding;
21     @Override
22     public void init(FilterConfig filterConfig) throws ServletException {
23         // TODO Auto-generated method stub
24         encoding=filterConfig.getInitParameter("encoding");
25         System.out.println("encoding:"+encoding);
26     }
27 
28     @Override
29     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
30             throws IOException, ServletException {
31         // TODO Auto-generated method stub
32         HttpServletRequest req = (HttpServletRequest)request;
33         req.setCharacterEncoding(encoding);
34         HttpServletResponse res = (HttpServletResponse)response;
35         res.setContentType("text/html;charset=" + encoding);
36         chain.doFilter(request, response);
37     }
38 
39     @Override
40     public void destroy() {
41         // TODO Auto-generated method stub
42 
43     }
44 
45 }

过滤参数化

上面代码是注解形式的过滤器参数化,配置在web.xml:

 1    <filter>
 2       <filter-name>CharacterEncodingFilter</filter-name>
 3       <filter-class>com.mingm.filter.CharacterEncodingFilter</filter-class>
 4       <init-param>
 5           <param-name>encoding</param-name>
 6           <param-value>UTF-8</param-value>
 7       </init-param>
 8       <init-param>
 9           <param-name>p1</param-name>
10           <param-value>v1</param-value>
11       </init-param>
12       <init-param>
13           <param-name>p2</param-name>
14           <param-value>v2</param-value>
15       </init-param>
16   </filter>
17    <filter-mapping>
18       <filter-name>CharacterEncodingFilter</filter-name>
19       <url-pattern>/*</url-pattern>
20   </filter-mapping> 

ServletRequest接口

ServletRequest是所有请求的顶层接口,代表任何请求

HttpServletRequest是Http协议请求的抽象接口,是J2EE标准

RequestFacade是HttpServletRequest接口的实现类,由Tomcat实现

url-pattern常用写法

/index.jsp - 执行资源精确匹配

/servlet/* - 前缀模糊匹配

*.jsp - 后缀模糊匹配

/与/*的区别

/指映射Web应用根路径,且只对Servlet生效

默认首页index.jsp会让/失效

/与/*含义不同,前者指向根路径.后者代表所有

过滤链开发注意事项

每一个过滤器应具有单独功能

过滤器执行顺序以<filter-mapping>为准

调用chain.doFilter()将请求向后传递

多端设备自动匹配

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 public class DeviceAdapterFilter implements Filter{
13 
14     @Override
15     public void init(FilterConfig filterConfig) throws ServletException {
16         // TODO Auto-generated method stub
17         
18     }
19 
20     @Override
21     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
22             throws IOException, ServletException {
23         // TODO Auto-generated method stub
24         HttpServletRequest req = (HttpServletRequest)request;
25         HttpServletResponse res = (HttpServletResponse)response;
26         /*
27          /index.html
28          PC: /desktop/index.html
29          MOBILE: /mobile/index.html
30          /test.html
31          PC: /desktop/test.html
32          MOBILE: /mobile/test.html
33          */
34         String uri = req.getRequestURI();
35         System.out.println("URI:" + uri);
36         if(uri.startsWith("/desktop") || uri.startsWith("/mobile")) {
37             chain.doFilter(request, response);
38         }else {
39             String userAgent = req.getHeader("user-agent").toLowerCase();
40             String targetURI="";
41             if(userAgent.indexOf("android")!=-1 || userAgent.indexOf("iphone") != -1) {
42                 targetURI = "/mobile" + uri;
43                 System.out.println("移动端设备正在访问,重新跳转URI:" + targetURI);
44                 res.sendRedirect(targetURI);
45             }else {
46                 targetURI = "/desktop" + uri;
47                 System.out.println("PC端设备正在访问,重新跳转URI:" + targetURI);
48                 res.sendRedirect(targetURI);
49             }
50         }
51     }
52 
53     @Override
54     public void destroy() {
55         // TODO Auto-generated method stub
56         
57     }
58 
59 }

web.xml

1   <filter>
2       <filter-name>DeviceAdapterFilter</filter-name>
3       <filter-class>com.mingm.filter.DeviceAdapterFilter</filter-class>
4   </filter>
5   <filter-mapping>
6       <filter-name>DeviceAdapterFilter</filter-name>
7       <url-pattern>*.html</url-pattern>
8   </filter-mapping>

 

posted @ 2020-09-12 13:21  mingmingn  阅读(161)  评论(0)    收藏  举报