现在的位置: 首页 > 综合 > 正文

11、过滤器Filter

2018年02月05日 ⁄ 综合 ⁄ 共 9190字 ⁄ 字号 评论关闭

了解Servlet过滤器的概念
了解Servlet过滤器的工作过程
掌握创建Servlet过滤器的方法
掌握发布Servlet过滤器的方法

1、Servlet过滤器的概念

Servlet过滤器是在Java Servlet规范2.3中定义的,它能够对Servlet容器的请求和响应对象进行检查和修改。
Servlet过滤器本身并不生成请求和响应对象,他只提供过滤作用。
Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容;
在Servlet被调用之后检查Response对象,修改responseHeader和Response内容。Servlet过滤器负责过滤的Web组件可以是Servlet、JSP或HTML文件

2、Servlet过滤器的过滤过程

 

3、Filter接口

所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:
init()、doFilter()、destory()

每一个过滤器都要在web容器部署描述符中,就是web.xml中进行部署

     - init(FilterConfig):这是Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用这个方法。在这个方法中可以读取web.xml文件中Servlet过滤器的初始化参数
    - doFilter(ServletRequest,ServletResponse,FilterChain):这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器
    - destroy():Servlet容器在销毁过滤器实例前调用该方法,在这个方法中可以释放Servlet过滤器占用的资源。

过滤器的链式请求处理过程FilterChain示意图:

过滤器如果出现错误,整个服务就将失败

4、一个具体的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;
import javax.servlet.http.HttpSession;

public class LoginFilter implements Filter
{

	public void destroy()
	{

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException
	{
		HttpServletRequest r = (HttpServletRequest)request;
		HttpSession session = r.getSession();
		String requestURI = r.getRequestURI();
		if(requestURI.endsWith("login.jsp") || requestURI.endsWith("MyLoginServlet"))
		{
			chain.doFilter(request, response);
			return;
		}
		
		if(null == session.getAttribute("user"))
		{
			((HttpServletResponse)response).sendRedirect("filter/login.jsp");
			return;
		}
		else
		{
			chain.doFilter(request, response);
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException
	{
		System.out.println("filter init invoke!");
	}

}

部署描述符中的配置:

<filter>
  	<filter-name>LoginFilter</filter-name>
  	<filter-class>com.cdtax.filter.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>LoginFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

一个使用filter过滤器的实例:一个输入页面comment.jsp,有username和comment两个输入域,提交后由一个servlet处理转向一个显示页面,一个过滤器对输入的内容进行过滤,username中含有123则替换为abc,comment中有wokao替换为****

comment.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 'comment.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="CommentServlet" method="post">
    	username:<input type="text" name="username"/><br/>
    	commnet:<textarea name="comment" rows="7" cols="7"></textarea><br/>
    	<input type="submit" value="submit"/>
    </form>
  </body>
</html>

CommentServlet:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CommentServlet extends HttpServlet
{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		 
		 req.getRequestDispatcher("commentResult.jsp").forward(req, resp);
	}
}

显示页面:commentResult.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 'commentResult.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>
    username:<%= request.getAttribute("username") %><br/>
    comment:<%= request.getAttribute("comment") %>
  </body>
</html>

过滤器:CommentFilter

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 CommentFilter implements Filter
{

	public void destroy()
	{

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException
	{
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		
		String username = req.getParameter("username");
		String comment = req.getParameter("comment");
		
		username = username.replace("123",	"abc");
		comment = comment.replace("wokao", "****");
		
		req.setAttribute("username", username);
		req.setAttribute("comment", comment);
		chain.doFilter(request, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException
	{

	}

}

web.xml中的部署

<filter>
  	<filter-name>CommentFilter</filter-name>
  	<filter-class>com.cdtax.filter.CommentFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>CommentFilter</filter-name>
  	<url-pattern>/CommentServlet</url-pattern>
  </filter-mapping>

5、串联Servlet过滤器的工作流程

客户并不知道过滤器的存在,过滤器完全是服务器端的行为

过滤器链的实例

info.jsp

<body>
    <form action="InfoServlet" method="post">
    	username:<input type="text" name="username"/><br/>
    	
    	<input type="submit" value="submit"/>"
    </form>
  </body>

InfoServlet:

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InfoServlet extends HttpServlet
{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		 System.out.println(req.getParameter("username"));
		 req.getRequestDispatcher("infoResult.jsp").forward(req, resp);
	}
}

infoResult.jsp:

<body>
    <%= request.getParameter("username") %>
  </body>

过滤器MyFilter1和MyFilter2

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 MyFilter1 implements Filter
{

	public void destroy()
	{

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException
	{
		System.out.println("Filter1 before chain.doFilter");
		chain.doFilter(request, response);
		System.out.println("Filter1 after chain.doFilter");

	}

	public void init(FilterConfig filterConfig) throws ServletException
	{

	}

}



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 MyFilter2 implements Filter
{

	public void destroy()
	{

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException
	{
		System.out.println("Filter2 before chain.doFilter");
		chain.doFilter(request, response);
		System.out.println("Filter2 after chain.doFilter");

	}

	public void init(FilterConfig filterConfig) throws ServletException
	{

	}

}

web.xml配置:

<filter>
  	<filter-name>MyFilter1</filter-name>
  	<filter-class>com.cdtax.filter.MyFilter1</filter-class>
  </filter>
  <filter>
  	<filter-name>MyFilter2</filter-name>
  	<filter-class>com.cdtax.filter.MyFilter2</filter-class>
  </filter>

<filter-mapping>
  	<filter-name>MyFilter1</filter-name>
  	<url-pattern>/InfoServlet</url-pattern>
  </filter-mapping>
  <filter-mapping>
  <filter-name>MyFilter2</filter-name>
  <url-pattern>/InfoServlet</url-pattern>
  </filter-mapping>

Filter的执行顺序是跟配置中的<filter-mapping>相关联的,哪个<filter-mapping>在前,就先执行哪个Filter,如将上面的配置改为

<filter-name>MyFilter2</filter-name>
  <url-pattern>/InfoServlet</url-pattern>
  </filter-mapping>
  <filter-mapping>
  	<filter-name>MyFilter1</filter-name>
  	<url-pattern>/InfoServlet</url-pattern>
  </filter-mapping>

其他不动,执行结果为:

Filter2 before chain.doFilter
Filter1 before chain.doFilter
wwww
Filter1 after chain.doFilter
Filter2 after chain.doFilter

执行的结果:

Filter1 before chain.doFilter
Filter2 before chain.doFilter
wwww
Filter2 after chain.doFilter
Filter1 after chain.doFilter

 

6、关于FilterConfig

在web.xml中filter可以带参数:

<filter>
  	<filter-name>CommentFilter</filter-name>
  	<filter-class>com.cdtax.filter.CommentFilter</filter-class>
  	<init-param>
  		<param-name>hello</param-name>
  		<param-value>world</param-value>
   	</init-param>
   	<init-param>
   		<param-name>zhang</param-name>
   		<param-value>li</param-value>
   	</init-param>
  </filter>

在Filter中通过FilterConfig获得参数的方法:

public void init(FilterConfig filterConfig) throws ServletException
	{
		String value1 = filterConfig.getInitParameter("hello");
		String value2 = filterConfig.getInitParameter("zhang");
		System.out.println(value1 + value2);
		
	
	}

通过FilterConfig可以获得ServletContext对象,也就是application,语法:

ServletContext sc = filterConfig.getServletContext();

相当于使用request:

ServletContext sc = request.getSession().getServletContext();

【上篇】
【下篇】

抱歉!评论已关闭.