1.Servlet API 定义三个接口类:Filter FilterChain 和FilterConfig,由Servlet容器进行调用和执行
1. 创建一个Filter l类
2.在web.xml 进行配置,url-pattern-->指定的要拦截的Jsp 资源
3. init() 对其进行初始化同时对其进行初始化
过滤请求 调用doFilter
FilterChain: 构成一个Filter链子 只有一个doFilter() 方法 便请求传递给下一个Filter,如果Filter最后一个传递给对象 ,多个Filter执行顺序与在<filter-mapping> 配置的顺序有关,Filter没有类继承只能直接实现接口
例子:
在Servlet3.0特性中,不需要在web.xml上去进行配置,直接在@WebFilter() 就行
但是其执行的顺序在web.xml中按照filter-mapping 但是在Servlet3.0特性中按照的 filter文件名.java 的首字母顺序执行 UserName.java 执行在passwordFilter.java 之后,所有我们调换其首字母
1 package com.FilterTest; 2 3 import java.io.IOException; 4 import javax.servlet.Filter; 5 import javax.servlet.FilterChain; 6 import javax.servlet.FilterConfig; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletRequest; 9 import javax.servlet.ServletResponse; 10 import javax.servlet.annotation.WebFilter; 11 import javax.servlet.annotation.WebInitParam; 12 13 /** 14 * Servlet Filter implementation class UserNameFilter 15 */ 16 @WebFilter( filterName="A",urlPatterns="/hello.jsp", 17 initParams={@WebInitParam(name="username", value="Tom")}) 18 public class UserNameFilter implements Filter { 19 20 /** 21 * Default constructor. 22 */ 23 public UserNameFilter() { 24 // TODO Auto-generated constructor stub 25 } 26 27 /** 28 * @see Filter#destroy() 29 */ 30 public void destroy() { 31 // TODO Auto-generated method stub 32 } 33 34 /** 35 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) 36 */ 37 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 38 // TODO Auto-generated method stub 39 // place your code here 40 System.out.println("doFilter"); 41 42 // 先对用户进行验证 输入的username与初始化设置username是否相等 43 String initUser=filterconfig.getInitParameter("username"); 44 System.out.println(initUser); 45 String username=request.getParameter("username"); 46 47 if(!username.equals(initUser)) 48 { 49 //就让其前往passwordFilter页面 50 request.setAttribute("message", "用户名不正确"); 51 request.getRequestDispatcher("/testa.jsp").forward(request, response); 52 return; 53 } 54 // pass the request along the filter chain passwordFilter 55 chain.doFilter(request, response); 56 } 57 private FilterConfig filterconfig; 58 /** 59 * @see Filter#init(FilterConfig) 60 */ 61 public void init(FilterConfig fConfig) throws ServletException { 62 // TODO Auto-generated method stub 63 this.filterconfig=fConfig; 64 } 65 66 }
View Code
1 <form action="hello.jsp" method="post"> 2 username:<input type="text" name="username" value="${ param.username}"/> 3 password:<input type="text" name="password"/> 4 <input type="submit" name="submit"/> 5 </form> 6 <font color="red" >${message }</font>
编写HttpFilter 让原生ServletRequest 变成HttpServletRequest
1 package com.FilterTest; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 /**将Filter 进行封装,将其转换成HttpFilter 15 * 自定义的HttpFilter 实现Filter接口*/ 16 17 public abstract class HttpFilter implements Filter{ 18 19 private FilterConfig filterConfig; 20 /**不建议覆盖此方法*/ 21 @Override 22 public void init(FilterConfig filterConfig) throws ServletException { 23 // TODO Auto-generated method stub 24 this.filterConfig=filterConfig; 25 init(); 26 } 27 /** 28 * 供子类初始化方法 ,可以通过getFilterConfig方法获取对象*/ 29 protected void init(){}; 30 31 /** 32 * 直接返回 init(ServletConfig) 的 FilterConfig 对象 33 */ 34 public FilterConfig getFilterConfig() { 35 return filterConfig; 36 } 37 38 public void setFilterConfig(FilterConfig filterConfig) { 39 this.filterConfig = filterConfig; 40 } 41 42 /**原生的doFilter方法,在内部将ServletRequest 转换成 HttpServletrequest 43 * 调用doFilter(HttpServletRequest request, HttpServletResponse response, 44 * FilterChain filterChain)方法 45 * 46 * 若编写 Filter 的过滤方法不建议直接继承该方法. 而建议继承 47 * doFilter(HttpServletRequest request, HttpServletResponse response, 48 * FilterChain filterChain) 方法*/ 49 @Override 50 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 51 throws IOException, ServletException { 52 // TODO Auto-generated method stub 53 HttpServletRequest request=(HttpServletRequest) req; 54 HttpServletResponse response=(HttpServletResponse) req; 55 56 doFilter(request,response,chain); 57 } 58 59 public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain); 60 61 @Override 62 public void destroy() { 63 // TODO Auto-generated method stub 64 65 } 66 67 }
doFilter中执行的顺序是类似于递归调用的方式
6.<dispatcher> 指定Filter拦截的资源被Servlet容器调用的方式:默认的REQUEST,
如下:如果采用GET、post---->1.jsp----转发-->目的.jsp ;由于默认是REQUEST则Filter不会对此继续拦截
必须修改@webFilter中dispatcher属性,这样才能在 通过转发和request方法的访问过程中 加上Filter
dispatcherTypes={DispatcherType.FORWARD,DispatcherType.FORWARD}
总结:
8.Filter 禁用缓存的:3个Http的响应字段可以禁止浏览器缓存
直接继承 Filter接口:进行强制转换
((HttpServletResponse) response).setDateHeader("Expires",-1);
9.字符编码的过滤器:
request.setCharacterEncoding("UTF-8");
在过滤器中进行字符编码,到达JSP之前,指定其中字符编码 同时在web.xml 上初始化encoding 的编码方式
1 package com.FilterTest; 2 3 import java.io.UnsupportedEncodingException; 4 5 import javax.servlet.FilterChain; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class EncodingFilter extends HttpFilter { 10 11 private String encoding; 12 protected void init() 13 { 14 this.encoding=getFilterConfig().getServletContext().getInitParameter("encoding"); 15 } 16 @Override 17 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) { 18 // TODO Auto-generated method stub 19 try { 20 request.setCharacterEncoding(encoding); 21 } catch (UnsupportedEncodingException e) { 22 // TODO Auto-generated catch block 23 e.printStackTrace(); 24 } 25 doFilter(request,response,chain); 26 } 27 28 }
1 package com.FilterTest; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 /**将Filter 进行封装,将其转换成HttpFilter 15 * 自定义的HttpFilter 实现Filter接口*/ 16 17 public abstract class HttpFilter implements Filter{ 18 19 private FilterConfig filterConfig; 20 /**不建议覆盖此方法*/ 21 @Override 22 public void init(FilterConfig filterConfig) throws ServletException { 23 // TODO Auto-generated method stub 24 this.filterConfig=filterConfig; 25 init(); 26 } 27 /** 28 * 供子类初始化方法 ,可以通过getFilterConfig方法获取对象*/ 29 protected void init(){}; 30 31 /** 32 * 直接返回 init(ServletConfig) 的 FilterConfig 对象 33 */ 34 public FilterConfig getFilterConfig() { 35 return filterConfig; 36 } 37 38 public void setFilterConfig(FilterConfig filterConfig) { 39 this.filterConfig = filterConfig; 40 } 41 42 /**原生的doFilter方法,在内部将ServletRequest 转换成 HttpServletrequest 43 * 调用doFilter(HttpServletRequest request, HttpServletResponse response, 44 * FilterChain filterChain)方法 45 * 46 * 若编写 Filter 的过滤方法不建议直接继承该方法. 而建议继承 47 * doFilter(HttpServletRequest request, HttpServletResponse response, 48 * FilterChain filterChain) 方法*/ 49 @Override 50 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 51 throws IOException, ServletException { 52 // TODO Auto-generated method stub 53 HttpServletRequest request=(HttpServletRequest) req; 54 HttpServletResponse response=(HttpServletResponse) req; 55 56 doFilter(request,response,chain); 57 } 58 59 public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain); 60 61 @Override 62 public void destroy() { 63 // TODO Auto-generated method stub 64 65 } 66 67 }
10.检测用户是否登录过:
要求 session.getAttribute(key) 这个key在web.xml 配置成 可以配置的方式
解决方法:系统中某些网页只有登录才能查看,设置一个Filter,当用户没有登录的话则重定向到登录页面
要求:session在检查的关键字做成可以配置的方式
1.URI:/Tomcat/filter/a.jsp
2.URL:http://localhost:8080/TomCat/filter/a.jsp
3.servletPath=/filter/a.jsp ---服务器内部的地址
以下是代码: 所有list登录经过Fileter进行处理,有些servletPath默认其通过
1.//1.获取请求的ServletPath
2.// 2.检查servletPath是否不需要检查的url
// 3.从session获取Seesionkey,不存在重新定向到登录页面---比较输入用户名是否正确,DAO在SQL查询并且比较
4. 用户名正确 放行
1 package com.FilterTest; 2 3 import java.io.IOException; 4 import java.util.Arrays; 5 import java.util.List; 6 7 import javax.servlet.FilterChain; 8 import javax.servlet.ServletContext; 9 import javax.servlet.ServletException; 10 import javax.servlet.annotation.WebFilter; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 @WebFilter("/filter/*") 14 public class LoginFilter extends HttpFilter { 15 16 //0.从web.xml 文件获取初始值 17 private String sessionKey; 18 private String redirectUrl; 19 private String uncheckedUrls; 20 21 @Override 22 protected void init() 23 { 24 // 获取初始化值 25 ServletContext servletcontext=getFilterConfig().getServletContext(); 26 sessionKey=servletcontext.getInitParameter("userSessionKey"); 27 redirectUrl=servletcontext.getInitParameter("redirectPage"); 28 uncheckedUrls=servletcontext.getInitParameter("uncheckedUrls"); 29 30 System.out.println(sessionKey); 31 System.out.println(redirectUrl); 32 System.out.println(uncheckedUrls); 33 } 34 @Override 35 public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { 36 // TODO Auto-generated method stub 37 //1.获取请求的ServletPath 38 //String requestURI=request.getRequestURI(); 39 //String requestURl=request.getRequestURL().toString(); 40 String servletPath=request.getServletPath(); 41 42 43 // 2.检查servletPath是否不需要检查的url 44 List<String> urs=Arrays.asList(uncheckedUrls.split(",")); 45 if(urs.contains(servletPath)) 46 { 47 // 直接放行 48 49 chain.doFilter(request, response); 50 return; 51 } 52 // 3.从session获取Seesionkey,不存在重新定向到登录页面 53 Object user=request.getSession().getAttribute(sessionKey); 54 if(user == null){ 55 response.sendRedirect(request.getContextPath() + redirectUrl); 56 return; 57 } 58 59 // 4.存在直接放行 60 chain.doFilter(request, response); 61 } 62 63 }
1 package com.FilterTest; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 /**将Filter 进行封装,将其转换成HttpFilter 15 * 自定义的HttpFilter 实现Filter接口*/ 16 17 public abstract class HttpFilter implements Filter{ 18 19 private FilterConfig filterConfig; 20 /**不建议覆盖此方法*/ 21 @Override 22 public void init(FilterConfig filterConfig) throws ServletException { 23 // TODO Auto-generated method stub 24 this.filterConfig=filterConfig; 25 init(); 26 } 27 /** 28 * 供子类初始化方法 ,可以通过getFilterConfig方法获取对象*/ 29 protected void init(){}; 30 31 /** 32 * 直接返回 init(ServletConfig) 的 FilterConfig 对象 33 */ 34 public FilterConfig getFilterConfig() { 35 return filterConfig; 36 } 37 38 public void setFilterConfig(FilterConfig filterConfig) { 39 this.filterConfig = filterConfig; 40 } 41 42 /**原生的doFilter方法,在内部将ServletRequest 转换成 HttpServletrequest 43 * 调用doFilter(HttpServletRequest request, HttpServletResponse response, 44 * FilterChain filterChain)方法 45 * 46 * 若编写 Filter 的过滤方法不建议直接继承该方法. 而建议继承 47 * doFilter(HttpServletRequest request, HttpServletResponse response, 48 * FilterChain filterChain) 方法*/ 49 @Override 50 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 51 throws IOException, ServletException { 52 // TODO Auto-generated method stub 53 HttpServletRequest request=(HttpServletRequest) req; 54 HttpServletResponse response=(HttpServletResponse) res; 55 56 doFilter(request,response,chain); 57 } 58 59 public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException; 60 61 @Override 62 public void destroy() { 63 // TODO Auto-generated method stub 64 65 } 66 67 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 3 <context-param> 4 <param-name>password</param-name> 5 <param-value>1234</param-value> 6 </context-param> 7 8 <!-- 用户信息登录放入到Ssesion的值 --> 9 <context-param> 10 <param-name>userSessionKey</param-name> 11 <param-value>USERSESSIONKEY</param-value> 12 </context-param> 13 14 <!-- 没有登录重定向页面 可以配置,成灵活的--> 15 <context-param> 16 <param-name>redirectPage</param-name> 17 <param-value>/filter/login.jsp</param-value> 18 </context-param> 19 <!-- 不需要拦截页面,自由访问 --> 20 <context-param> 21 <param-name>uncheckedUrls</param-name> 22 <param-value>/filter/login.jsp,/filter/a.jsp,/filter/list.jsp,/filter/dologin.jsp</param-value> 23 </context-param> 24 </web-app>