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>

浙公网安备 33010602011771号