一 什么是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>