一 什么是filter
Filter是sun公司中servlet2.3后增加的一个新功能.Servlet规范中三个技术 Servlet Listener Filter在javaEE中定义了一个接口。
在请求进入的时候进行拦截或者在请求出来的时候进行拦截,对数据做拦截过滤操作。
二 filter的作用
javax.servlet.Filter来描述过滤器通过Filter可以拦截访问web资源的请求与响应操作.WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
三 怎么创建一个filter
1. 创建一个类实现javax.servlet.Filter接口
public class Myfiter implements Filter{ public void destroy() {} public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { System.out.println("拦截开始请求"); chain.doFilter(arg0, arg1); System.out.println("拦截结束请求"); } public void init(FilterConfig arg0) throws ServletException {} }
2.得写接口方法
3.在web.xml文件中配置Filter
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>Myfiter</filter-name> <filter-class>xiao.it.java.Myfiter</filter-class> </filter> <filter-mapping> <filter-name>Myfiter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
4测试结果
五月 05, 2018 11:02:32 上午 org.apache.catalina.core.StandardService startInternal 信息: Starting service Catalina 五月 05, 2018 11:02:32 上午 org.apache.catalina.core.StandardEngine startInternal 信息: Starting Servlet Engine: Apache Tomcat/7.0.42 五月 05, 2018 11:02:33 上午 org.apache.catalina.util.SessionIdGenerator createSecureRandom 信息: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [411] milliseconds. 五月 05, 2018 11:02:33 上午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["http-bio-8080"] 五月 05, 2018 11:02:33 上午 org.apache.coyote.AbstractProtocol start 信息: Starting ProtocolHandler ["ajp-bio-8009"] 五月 05, 2018 11:02:33 上午 org.apache.catalina.startup.Catalina start 信息: Server startup in 775 ms 拦截开始请求 用户被绑定 拦截结束请求
FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
四 filter的生命周期
当服务器启动,会创建Filter对象,并调用init方法,只调用一次。
当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法。
当服务器关闭时,会调用Filter的destroy方法来进行销毁操作。
五 filterConfig
Web.xml下面filter的配置信息
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>Myfiter</filter-name> <filter-class>xiao.it.java.Myfiter</filter-class> <init-param> <param-name>encode</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Myfiter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
服务器启动的时候,我们通过获取filter的initparam对filter进行处理,对所有的服务请求做编码的处理工作,如下面的代码所示
public class Myfiter implements Filter{ FilterConfig filterConfig=null; public void destroy() {} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String initParameter = filterConfig.getInitParameter("encode"); //初始华参数 System.out.println(initParameter); request.setCharacterEncoding(initParameter); chain.doFilter(request, response); } public void init(FilterConfig config) throws ServletException { //服务器启动的时候 加载filter的配置信息 this.filterConfig=config; } }
六 filter的配置
6.1代码准备
@WebServlet("/Servlet1") public class Servlet1 extends HttpServlet { private static final long serialVersionUID = 1L; public Servlet1() { super(); // TODO Auto-generated constructor stub } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } } @WebServlet("/Servlet2") public class Servlet2 extends HttpServlet { private static final long serialVersionUID = 1L; public Servlet2() { super(); // TODO Auto-generated constructor stub } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <filter> <filter-name>Myfiter</filter-name> <filter-class>xiao.it.java.Myfiter</filter-class> <init-param> <param-name>encode</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Myfiter</filter-name> <!-- <url-pattern>/*</url-pattern> --> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <servlet> <servlet-name>Servlet1</servlet-name> <servlet-class>xiao.it.servlet.Servlet1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet1</servlet-name> <url-pattern>/servlet/demo1</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet2</servlet-name> <servlet-class>xiao.it.servlet.Servlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet2</servlet-name> <url-pattern>/servlet/demo2</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
6.2 Filter基本配置介绍
<filter> <filter-name>filter名称</filter-name> <filter-class>filter类全名</filter-class> </filter> <filter-mapping> <filter-name>filter名称</filter-name> <url-pattern>映射路径</url-pattern> </filter-mapping>
6.3关于url-pattern配置
1.完全匹配
要求必须以"/"开始.
2.目录匹配
要求必须以"/"开始,以*结束.
3.扩展名匹配
不能以"/"开始,以*.xxx结束.
6.4关于servlet-name配置
针对于servlet拦截的配置 <servlet-name>配置,在Filter中它的配置项上有一个标签
,<servlet-name>它用于设置当前Filter拦截哪一个servlet,是通过servlet的name来确定的。
也就是在如上代码准备的地方,不在制定拦截什么路径了,而是指定拦截哪个servlet,其他的servlet将不会被拦截。
<filter-mapping> <filter-name>Myfiter</filter-name> <!-- <url-pattern>/*</url-pattern> --> <!-- <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> --> <filter-name>Servlet2</filter-name> </filter-mapping>
6.5关于dispatcher配置
1.REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
2.FORWARD 它描述的是请求转发的拦截方式配置
3.ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
4.INCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用
<filter-mapping> <filter-name>Myfiter</filter-name> <!-- <url-pattern>/*</url-pattern> --> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
如上所示的代码配置,指定了在什么情况下拦截,比如当两个servlet通过forward做请求转发的时候,比如一个servlert在include另一个servlet的时候,或者系统异常的时候。默认情况下是request的请求做拦截,其他的不拦截,如果forward也要拦截,那就得两个都做配置
request.getRequestDispatcher("/servlet2/demo2").forward(request, response); request.getRequestDispatcher("/servlet2/demo2").include(request, response);
七 filter实现自动登陆
思路:首先用户在界面上点击记住密码的复选框,这时在服务器端后台可以把账号密码放入Cookie中带到界面上,这个cookie可以指定它的生命周期,通过response属性带到界面上,此时如果我们关闭界面的session的时候,数据就会缓存到浏览器中,下一次访问页面的时候就通过filter去把cookie中的数据拿出来跟数据库校验之后再放入绘画中,这样就实现了自动登陆,打开登陆页面的时候,也可以把cookie中的用户名密码进行回填。
7.1 界面
<%@page import="org.apache.tomcat.util.http.Cookies"%> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <% Cookie cookie=null; String name=null; String pass=null; Cookie[] cookies=request.getCookies(); if(null!=cookies){ for(Cookie co:cookies){ if(co.getName().equals("user")){ cookie=co; } } } if(cookie!=null){ String str=cookie.getValue(); String st[]=str.split(","); name=st[0]; pass=st[1]; } %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form action="servlet/demo1" method="post"> <table> <tr> <td>用户名</td> <td><input name="uname" value="<%=name==null?"":name%>"></td> </tr> <tr> <td>密码</td> <td><input name="upass" value="<%=pass==null?"":pass%>"/></td> </tr> <tr> <td colspan="2"> 记住用户名:<input name="isred" type="checkbox"> </td> </tr> </table> <input type="submit"> </form> </body> </html>
7.2 服务类
public class Servlet1 extends HttpServlet { public static final String uname="xiao"; public static final String upass="wen"; private static final long serialVersionUID = 1L; public Servlet1() { super(); // TODO Auto-generated constructor stub } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String name = request.getParameter("uname"); String pass = request.getParameter("upass"); String isred= request.getParameter("isred"); Cookie cookie=new Cookie("user", name+","+pass); cookie.setPath("/"); if(isred!=null){ //最大保存7天 cookie.setMaxAge(7*60*60*1000*24); response.addCookie(cookie); }else{ cookie.setMaxAge(0); cookie.setValue(null); response.addCookie(cookie); } if(name.equals(uname)){ request.getSession().setAttribute("user", name+"&"+pass); request.getRequestDispatcher("/home.jsp").forward(request, response); }else{ request.getRequestDispatcher("/home.jsp").forward(request, response); } }
7.3 filter类
public class LoginFileter implements Filter{ @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub HttpServletRequest httpRequest=(HttpServletRequest) request; Cookie[] cookies = httpRequest.getCookies(); if(null!=cookies){ for(Cookie coo:cookies){ if(null==coo)continue; String name = coo.getName(); if("user".equals(name)){ String value = coo.getValue(); String[] str=value.split("&"); //这里通过数据库 进行用户名密码的比较 //User u=userService.checkUser(str) httpRequest.getSession().setAttribute("user", str); } } } chain.doFilter(request, response); } @Override public void init(FilterConfig arg0) throws ServletException { } }
7.4 web.xml中的配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <filter> <filter-name>Myfiter</filter-name> <filter-class>xiao.it.servlet.LoginFileter</filter-class> <init-param> <param-name>encode</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>Myfiter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>Servlet1</servlet-name> <servlet-class>xiao.it.servlet.Servlet1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet1</servlet-name> <url-pattern>/servlet/demo1/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>