一、Filter概述
filter功能.它使用户可以改变一个request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在response离开servlet时处理response.换种说法,filter其实是一个“servlet chaining“(servlet 链).
包括
1. 在servlet被调用之前截获;
2. 在servlet被调用之前检查servlet request;
3. 根据需要修改request头和request数据;
4. 根据需要修改response头和response数据;
5. 在servlet被调用之后截获.
你能够配置一个filter 到一个或多个servlet;单个servlet或servlet组能够被多个filter 使用。几个实用的filter 包括:用户辨认filter,日志filter,审核filter,加密filter,符号filter,能改变xml内容的XSLT filter等。
一个filter必须实现javax.servlet.Filter。
三个方法
1. void setFilterConfig(FilterConfig config) //设置filter 的配置对象;
2. FilterConfig getFilterConfig() //返回filter的配置对象;
3. void doFilter(ServletRequest req,ServletResponse res,FilterChain chain) //执行filter 的工作.
注:现setFilterConfig和getFilterConfig方法已取消,代之为init(FilterConfig config)和destory()方法。[3]
服务器每次只调用setFilterConfig方法一次准备filter 的处理;调用doFilter方法多次以处理不同的请求.FilterConfig接口有方法可以找到filter名字及初始化参数信息.服务器可以设置FilterConfig为空来指明filter已经终结.
每一个filter从doFilter()方法中得到当前的request及response.在这个方法里,可以进行任何的针对request及response的操作.(包括收集数据,包装数据等).filter调用chain.doFilter()方法把控制权交给下一个filter.一个filter在doFilter()方法中结束.如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下一个filter.
一个filter可以包装request 或response以改变几个方法和提供用户定制的属性.Api2.3提供了HttpServletRequestWrapper 和HttpServletResponseWrapper来实现.它们能分派最初的request和response.如果要改变一个方法的特性,必须继承wapper和重写方法.下面是一段简单的日志filter用来记录所有request的持续时间
二、创建Filter类
package Filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class LogFilter implements Filter{
//FilterConfig用于可访问Filter的配置信息
private FilterConfig filterConfig;
//实现销毁方法
public void destroy() {
this.filterConfig=null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//-----------下面代码对用户请求进行预处理-----------
//获取ServletContext对象,用于记录日志
ServletContext context=this.filterConfig.getServletContext();
long before=System.currentTimeMillis();
System.out.println("开始过滤............");
//将请求转换成HttpServletRequest对象
HttpServletRequest hrequest=(HttpServletRequest)request;
//输出提示信息
System.out.println("Filter已经获取到用户请求地址:"+hrequest.getServletPath());
//Filter只是链式处理,请求依然放到目的地址,这个方法决定是否放行
chain.doFilter(hrequest, response);
//------------下面代码用于对服务器响应执行后处理------------
long after=System.currentTimeMillis();
//输出提示信息
System.out.println("过滤结束、、、、、、");
System.out.println("请求被定位到 "+hrequest.getRequestURI()+"所花时间为"+(after-before));
}
//实现初始化方法
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig=filterConfig;
}
}
三、配置Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 定义Filter -->
<filter>
<filter-name>logFilter</filter-name>
<filter-class>Filter.LogFilter</filter-class>
</filter>
<!-- 定义Filter拦截的URL地址 -->
<filter-mapping>
<filter-name>logFilter</filter-name>
<!-- 负责拦截的URL,/*表示拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
四、测试类
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Login</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
${tip}<br>
<form action="login?action=service" method="post">
名称:<input type="text" name="user"><br>
密码:<input type="text" name="pass"><br/>
<input type="submit" value="登录"><input type="reset" value="重置">
</form>
</body>
</html>
输出:
开始过滤............
Filter已经获取到用户请求地址:/index.jsp
过滤结束、、、、、、
请求被定位到 /webPrj/index.jsp所花时间为56
开始过滤............
Filter已经获取到用户请求地址:/login
五、综合例子
1、Filter类
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.HttpSession;
public class AuthorityFilter implements Filter{
private FilterConfig config;
//销毁方法
public void destroy() {
this.config=null;
}
//Filter的核心方法
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
String encode=config.getInitParameter("encode");
String indexPage=config.getInitParameter("indexPage");
String shopPage=config.getInitParameter("shopPage");
//设置编码字符集
request.setCharacterEncoding(encode);
HttpServletRequest requ=(HttpServletRequest)request;
//获取用户请求页面
String requestPath=requ.getServletPath();
HttpSession session=requ.getSession(true);
//如果session为空,则说明用户没有登录
if(session.getAttribute("user")==null && !requestPath.endsWith(indexPage) && !requestPath.endsWith(shopPage) && !requestPath.endsWith("login")){
//forward到首页
request.setAttribute("tip","你还没有登录");
request.getRequestDispatcher(indexPage).forward(request, response);
}else{//放行
chain.doFilter(request, response);
}
//chain.doFilter(request, response);
}
//初始化
public void init(FilterConfig config) throws ServletException {
this.config=config;
}
}
2、请求Servlet
package Login;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
System.out.println("##################################");
String user=String.valueOf(request.getAttribute("user"));
String pass=String.valueOf(request.getAttribute("pass"));
HttpSession session=request.getSession();
session.setAttribute("user", user);
session.setAttribute("pass", pass);
try {
//转发
//request.getRequestDispatcher("/shop.jsp").forward(request, response);
//重定向
response.sendRedirect("/webPrj/shop.jsp");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 定义Filter -->
<filter>
<filter-name>logFilter</filter-name>
<filter-class>Filter.LogFilter</filter-class>
</filter>
<!-- 定义Filter拦截的URL地址 -->
<filter-mapping>
<filter-name>logFilter</filter-name>
<!-- 负责拦截的URL,/*表示拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 定义AuthorityFilter -->
<filter>
<filter-name>authority</filter-name>
<filter-class>Filter.AuthorityFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>indexPage</param-name>
<param-value>/index.jsp</param-value>
</init-param>
<init-param>
<param-name>shopPage</param-name>
<param-value>/shop.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>authority</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 登录servlet -->
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>Login.LoginServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
4、index.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>Login</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
${tip}<br>
<form action="login?action=service" method="post">
名称:<input type="text" name="user"><br>
密码:<input type="text" name="pass"><br/>
<input type="submit" value="登录"><input type="reset" value="重置">
</form>
</body>
</html>
5、shop.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'shop.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="buy.jsp">
书籍:<input type="checkbox" name="item" value="book">
电脑:<input type="checkbox" name="item" value="computer">
汽车:<input type="checkbox" name="item" value="car">
<input type="submit" value="提交">
</form>
</body>
</html>
结果:对没有登录的用户进行相对应的拦截请求