Servlet(5)

1.java Servlet Filter(过滤器)
Filter是Servlet的过滤器,是Servlet 2.3规范中新增加的一个功能,主要用于完成一些通用的操作,如编码的过滤、判断用户的登录状态等。
Filter 被称为过滤器,其主要作用是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊功能.
在这里插入图片描述

注意:过滤器是部署在服务器上的。
当用户通过浏览器访问服务器中的目标资源时,首先会被 Filter 拦截,在 Filter 中进行预处理操作,然后再将请求转发给目标资源。当服务器接收到这个请求后会对其进行响应,在服务器处理响应的过程中,也需要将响应结果经过滤器处理后,才发送给客户端。
本质上,Filter 过滤器就是一个实现了 javax.servlet.Filter 接口的类,在 javax.servlet.Filter 接口中定义了三个方法
在这里插入图片描述

表中的三个方法都是可以表现 Filter 生命周期的方法,其中 init() 方法在 Web 应用程序加载时会被调用,destroy() 方法在 Web 应用程序卸载(或关闭)时被调用,这两个方法都只会被调用一次,而 doFilter() 方法会被调用多次(只要客户端有请求时就会被调用),Filter 所有的工作集中在 doFilter() 方法中。
下面通过案例演示 Filter 程序如何对 Servlet 程序的调用过程进行拦截。
1、创建一个Servlet,充当目标资源

package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyTestServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("MyTestServlet----");
		PrintWriter  out=resp.getWriter();
		out.write("Hello MyServlet");
		out.close();
	}
}

2.创建过滤器

  1. 1、创建新类,实现javax.servlet.Filter接口
  2. 重写init、doFilter、destroy方法
  3. 在doFilter中编写具体过滤动作
  4. Web.xml配置过滤器
package com.wangxing.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;
public class MyTestFilter implements Filter{
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("init方法初始化过滤器");
	}
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("doFilter方法过滤请求/响应对象");
		//FilterChain chain---过滤器链对象
		//doFilter(req, resp)---将请求/响应对象传递给下一个过滤器/目标资源
		chain.doFilter(req, resp);
	}
	@Override
	public void destroy() {
		System.out.println("destroy方法销毁过滤器对象");
	}
}

Web.xml

<filter>
  	<filter-name>myfilter1</filter-name>
  	<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>myfilter1</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping> 
  <servlet>
  	<servlet-name>mytest</servlet-name>
  	<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mytest</servlet-name>
  	<url-pattern>/mytest</url-pattern>
  </servlet-mapping>

测试http://localhost:8080/TestFilterDemo1/mytest

注意:过滤器可以直接对用户的请求作出响应,而不需要Servlet/目标资源的处理。
2.Java Servlet Filter的两种映射方式
创建 Filter 后,在 web.xml 中的对应配置信息就是 Filter 映射。Filter 的映射方式可分为两种。
1.使用通配符拦截用户的所有请求【–所有请求】

<filter>
  	<filter-name>myfilter1</filter-name>
  	<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>myfilter1</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping> 

在这里插入图片描述

2.拦截不同方式的访问请求
在 web.xml 文件中,每一个 元素都可以配置一个 Filter 所负责拦截的资源。在 元素中有一个特殊的子元素 ,该元素用于指定过滤器所拦截的资源被 Servlet 容器调用的方式。 元素的值共有四个。
在这里插入图片描述

例如:

<filter>
  	<filter-name>myfilter1</filter-name>
  	<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>myfilter1</filter-name>
  	<url-pattern>/*</url-pattern>
  	<dispatcher>FORWARD</dispatcher>
  </filter-mapping> 

例如:
当FORWARD表示通过RequestDispatcher 的 forward() 方法访问资源的时候才会使用当前配置的过滤器。当我们发送一个请求的时候,没有使用RequestDispatcher 的 forward() 方法时,是不会使用当前配置的过滤器。

3.拦截不同访问路径的访问请求
通过设置 元素中的指定不同的访问路径,来确定哪些资源可以访问当前过滤器,哪些资源不可以访问当前过滤器。

<filter>
  	<filter-name>myfilter1</filter-name>
  	<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
  </filter>
   <filter-mapping>
  	<filter-name>myfilter1</filter-name>
  	<url-pattern>/mytest</url-pattern>
  </filter-mapping> 
  
  <filter>
  	<filter-name>myfilter2</filter-name>
  	<filter-class>com.wangxing.filter.MyOtherFilter</filter-class>
  </filter>
   <filter-mapping>
  	<filter-name>myfilter2</filter-name>
  	<url-pattern>/myother</url-pattern>
  </filter-mapping> 
  
  <servlet>
  	<servlet-name>mytest</servlet-name>
  	<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mytest</servlet-name>
  	<url-pattern>/mytest</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>myother</servlet-name>
  	<servlet-class>com.wangxing.servlet.OtherTestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>myother</servlet-name>
  	<url-pattern>/myother</url-pattern>
  </servlet-mapping>

http://localhost:8080/TestFilterDemo3/mytest
在这里插入图片描述

http://localhost:8080/TestFilterDemo3/myother
在这里插入图片描述

3.FilterChain(过滤器链)详解
在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以针对某一个 URL 进行拦截。如果多个 Filter 程序都对同一个 URL 进行拦截,那么这些 Filter 就会组成一个Filter 链(也称过滤器链)。
Filter 链用 FilterChain 对象表示,FilterChain 对象中有一个 doFilter() 方法,该方法的作用是让 Filter 链上的当前过滤器放行,使请求进入下一个 Filter。
在这里插入图片描述

在上图中,当浏览器访问 Web 服务器中的资源时,需要经过两个过滤器 Filter1 和 Filter2。首先 Filter1 会对这个请求进行拦截,在 Filter1 中处理完请求后,通过Filter 链 FilterChain 对象调用 doFilter() 方法将请求传递给 Filter2,Filter2 处理用户请求后同样FilterChain 对象调用 doFilter() 方法,最终将请求发送给目标资源。当 Web 服务器对这个请求做出响应时,也会被过滤器拦截,但这个拦截顺序与之前相反,最终将响应结果发送给客户端浏览器。
在这里插入图片描述

例如:

<filter>
  	<filter-name>base</filter-name>
  	<filter-class>com.wangxing.filter.BaseFilter</filter-class>
  </filter>
   <filter-mapping>
  	<filter-name>base</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping> 
  
  <filter>
  	<filter-name>myfilter2</filter-name>
  	<filter-class>com.wangxing.filter.MyOtherFilter</filter-class>
  </filter>
   <filter-mapping>
  	<filter-name>myfilter2</filter-name>
  	<url-pattern>/mytest</url-pattern>
  </filter-mapping> 

   <filter>
  	<filter-name>myfilter1</filter-name>
  	<filter-class>com.wangxing.filter.MyTestFilter</filter-class>
  </filter>
   <filter-mapping>
  	<filter-name>myfilter1</filter-name>
  	<url-pattern>/mytest</url-pattern>
  </filter-mapping> 
  

  <servlet>
  	<servlet-name>mytest</servlet-name>
  	<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mytest</servlet-name>
  	<url-pattern>/mytest</url-pattern>
  </servlet-mapping>

http://localhost:8080/TestFilterDemo3/mytest
在这里插入图片描述

过滤器链中的每一个过滤器在执行的时候,与在web.xml文件中配置的顺序一致。
4.FilterConfig接口及其使用方法详解
FilterConfig接口与我们前面学习的ServletConfig接口相似。
FilterConfig 是 Servlet API 提供的一个用于获取 Filter 程序在 web.xml 文件中的配置信息的接口,该接口封装了 Filter 程序在 web.xml 中的所有注册信息,并且提供了一系列获取这些配置信息的方法。
在这里插入图片描述

测试FilterConfig的接口方法

package com.wangxing.filter;
import java.io.IOException;
import java.util.Enumeration;
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 MyTestFilter implements Filter{
	@Override
	public void init(FilterConfig config) throws ServletException {
		System.out.println("init方法初始化过滤器");
		//测试FilterConfig接口对象的常用方法
		//String getFilterName()--- web.xml 文件中为 Filter 所设置的名称.
		String filtername=config.getFilterName();
		System.out.println("filtername=="+filtername);
		//String getInitParameter(String name)---得到web.xml文件中配置的指定的初始化参数值
		String myname=config.getInitParameter("myname");
		System.out.println("myname=="+myname);
		//Enumeration getInitParameterNames()---得到web.xml文件中配置的初始化参数的名称。
		Enumeration<String>  initnameString=config.getInitParameterNames();
		  // 遍历所有的初始化参数名,得到相应的参数值并打印
        while (initnameString.hasMoreElements()) {
          String paramname = initnameString.nextElement();
          String value = config.getInitParameter(paramname);
          System.out.println("初始化信息=="+paramname+"="+value);
        }
	}
	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("MyTestFilter---doFilter方法过滤请求/响应对象");
		chain.doFilter(req, resp);
	}
	@Override
	public void destroy() {
		System.out.println("destroy方法销毁过滤器对象");
	}
}

Web.xml

<filter>
     <filter-name>myfilter</filter-name>
     <filter-class>com.wangxing.filter.MyTestFilter</filter-class>
     <init-param>
     	<param-name>myname</param-name>
     	<param-value>zhangsan</param-value>
     </init-param>
      <init-param>
     	<param-name>myaddress</param-name>
     	<param-value>西安</param-value>
     </init-param>
  </filter>
  <filter-mapping>
  	<filter-name>myfilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

启动服务器就能看到执行结果
在这里插入图片描述

5.Servlet Filter实现全站统一编码,解决中文乱码问题
注意:tomcat8以后默认编码格式是utf-8;7之前的都是iso8859-1

package com.wangxing.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;

/**
 * 编码过滤器【全站统一编码,解决中文乱码问题】
 * @author Administrator
 *
 */
public class EncodingFilter implements Filter{
	private String encoding="utf-8";
	@Override
	public void init(FilterConfig confing) throws ServletException {
		this.encoding=confing.getInitParameter("encoding");
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//转换ServletRequest为HttpServletRequest
		HttpServletRequest req=(HttpServletRequest)request;
		//转换ServletResponse为HttpServletResponse
		HttpServletResponse resp=(HttpServletResponse)response;
		//设置请求和响应的字符编码
		//解决post请求的中文乱码
		req.setCharacterEncoding(this.encoding);
		resp.setCharacterEncoding(this.encoding);
		resp.setContentType("text/html;charset="+this.encoding);
		//解决get请求的中文乱码
		//重写getParameter方法
		// 对 request 进行包装
        CharacterRequest characterRequest = new CharacterRequest(req,this.encoding);
        chain.doFilter(characterRequest, resp);
	}
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
}
package com.wangxing.filter;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
 *  对 request 进行包装
 * @author Administrator
 *
 */
public class CharacterRequest extends HttpServletRequestWrapper {
	private HttpServletRequest request;
	private String encoding="utf-8";
	public CharacterRequest(HttpServletRequest request,String encoding) {
		super(request);
		this.request=request;
		this.encoding=encoding;
	}
	
	@Override
	public String getParameter(String name) {
		String value = request.getParameter(name);
		if (value == null) {
	          return null;
	        }
		//得到请求的提交方式
		String method = request.getMethod(); 
		if ("get".equalsIgnoreCase(method)) {
            try {
            	//tomcat8以后默认编码格式是utf-8;7之前的都是iso8859-1
                value = new String(value.getBytes(this.encoding), this.encoding);
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
		return value;
	}
}
package com.wangxing.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyTestServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("MyTestServlet----");
		String myname=req.getParameter("myname");
		System.out.println("myname=="+myname);
		PrintWriter  out=resp.getWriter();
		out.write("Hello MyServlet==myname=="+myname);
		out.close();
	}
}

Web.xml

<filter>
  	<filter-name>encodingfilter</filter-name>
  	<filter-class>com.wangxing.filter.EncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingfilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <servlet>
  	<servlet-name>mytest</servlet-name>
  	<servlet-class>com.wangxing.servlet.MyTestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mytest</servlet-name>
  	<url-pattern>/mytest</url-pattern>
  </servlet-mapping>

测试
http://localhost:8080/EncodingFilter/mytest?myname=%E5%BC%A0%E4%B8%89

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/guoguo0717/article/details/109186545