本文共 9546 字,大约阅读时间需要 31 分钟。
理解过滤器的作用
掌握过滤器的开发技巧
掌握项目中过滤器的应用场景
案例:
MyFirstFilter.java
package filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class MyFirstFilter implements Filter{ @Override public void destroy() { // TODO Auto-generated method stub System.out.println("过滤器已被销毁"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("过滤器已生效");// 将请求与响应对象随着过滤链向后传递 chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub System.out.println("过滤器初始化成功"); } }
配置web.xml 后面会讲到使用注解的方式配置过滤器
first-filter index.html index.htm index.jsp default.html default.htm default.jsp MyFirstFilter filter.MyFirstFilter MyFirstFilter /*
随便编写两个页面测试一下过滤器是否生效
index.html
Insert title here 我是默认首页
HelloServlet.java
package filter;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Servlet implementation class HelloServlet */@WebServlet("/hello")public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public HelloServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Hello World!!!"); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); }}
Tomcat启动应用加载时:初始化 - Filter.init()
程序运行过程中:提供服务 - Filter.doFilter()
web应用重启或关闭时:销毁 - Filter.destroy()
过滤器对象在Web应用启动时被创建且全局唯一
唯一的过滤器对象在并发环境中采用“多线程”提供服务
在Tomcat3.0版本之后默认对注解进行支持,在应用程序启动时Tomcat对每一个字节码文件类进行扫描,检查注解实现配置
配置web.xml形式过滤器要比注解形式的过滤器先执行
import javax.servlet.annotation.WebFilter;@WebFilter(filterName="MyFirstFilter",urlPatterns="/*")public class MyFirstFilter implements Filter{ ...
配置形式维护更好,适合应用全局过滤
注解形式开发体验更好,适用于小型项目敏捷开发
建议项目中统一使用配置或注解形式,否则两者混用会使项目难以维护
Web中文乱码的解决
除了第一点需要在server.xml中配置之外,其他两个都需要在代码中手动编写,在程序开发过程中少写任何一个都可能出现乱码问题,字符集过滤器的作用就是对所有请求进行前置处理,将请求与响应的字符集进行同一的设置,在使用servlet开发时就不需要写这两行代码来设置了,可以极大的降低程序员开发出错的风险。
CharacterEncodingFilter.java
package filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*")public class CharacterEncodingFilter implements Filter { @Override public void destroy() { // 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; req.setCharacterEncoding("UTF-8"); HttpServletResponse res = (HttpServletResponse)response; res.setContentType("text/html;charset=UTF-8"); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub }}
优化字符集过滤器
将可能会产生变化的字符集编码放到web.xml,可以方便的对程序进行调整,而且不需要重启系统编译就可以生效,在大多数开发中,过滤器中的一些可变的选项都进行参数化设置
配置web.xml进行参数化设置
web.xml
first-filter index.html index.htm index.jsp default.html default.htm default.jsp CharacterEncodingFilter filter.CharacterEncodingFilter encoding GBK CharacterEncodingFilter /*
CharacterEncodingFilter.java 在init中使用filterConfig.getInitParameter()接收参数
package filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;//@WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*")public class CharacterEncodingFilter implements Filter { private String encoding; @Override public void destroy() { // 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; req.setCharacterEncoding(encoding); HttpServletResponse res = (HttpServletResponse)response; res.setContentType("text/html;charset="+encoding); chain.doFilter(req, res); } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub encoding = filterConfig.getInitParameter("encoding"); System.out.println("encoding:"+encoding); }}
使用注解的形式进行参数化设置
CharacterEncodingFilter.java
import javax.servlet.annotation.WebFilter;import javax.servlet.annotation.WebInitParam;@WebFilter(filterName="CharacterEncodingFilter",urlPatterns="/*", initParams= { @WebInitParam(name="encoding",value="UTF-8")// @WebInitParam(name="p1",value="v1") })public class CharacterEncodingFilter implements Filter { ...
映射的问题
如果想同时映射多个规则,写多个filter-mapping即可,只要保持filter-mapping中的filter-name与filter中的对应,写不同的url-pattern
注解形式设置过滤范围
也是直接设置即可,如果要设置多个规则,映射到大括号数组
@WebFilter(filterName="CharacterEncodingFilter",urlPatterns={ "/*","/servlet/*","*.jsp"})
在实际开发过程中这种复杂的配置,建议优先考虑配置形式
根据访问的设备不同显示不同的网页
DeviceAdapterFilter.java 判断设备过滤器
package filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class DeviceAdapterFilter implements Filter { @Override public void destroy() { // 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; String uri = req.getRequestURI(); System.out.println(uri);// 判断字符串是否以某个字符串开始/结尾// uri.startsWith("")// uri.endsWith("") if(uri.startsWith("/desktop") || uri.startsWith("/mobile")) { chain.doFilter(req, res); }else { 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:"); //重新访问新的uri,中断当前过滤器重新进入 res.sendRedirect(targetURI); }else { targetURI = "/desktop"+uri; System.out.println("PC端设备正在访问,重新跳转uri:"); res.sendRedirect(targetURI); } } } @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub }}
web.xml 配置过滤器
DeviceAdapterFilter filter.DeviceAdapterFilter DeviceAdapterFilter *.html
/desktop/index.html
Insert title here 桌面端
/mobile/index.html
Insert title here 移动端
转载地址:http://ydzwb.baihongyu.com/