1. 程式人生 > >javaee之過濾器

javaee之過濾器

過濾器Filter:
一、生命週期
init():初始化,在建立過濾器物件的時候會被呼叫。在過濾器在web應用啟動時建立,就只建立一次,以後再呼叫也不會初始化
doFilter():執行過濾的主要方法,用於過濾請求和響應,請求一次就呼叫一次,可以呼叫多次
destory():銷燬方法,過濾器物件銷燬的時候會被呼叫,也只是呼叫一次。


二、過濾器的作用:
Filter和Servlet一樣都是在伺服器中執行的,因此也是需要在web.xml進行配置
過濾器實現了Filter介面,用於在請求資源或者響應資源,或者請求和響應資源的時候,執行過濾任務


首先定義一個過濾器類

package c_example_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.HttpServletRequestWrapper;

/**
 * 過濾器首先要實現javax.servlet的Filter介面,並且實現其中的方法
 * @author Mao
 *
 */
public class demo1 implements Filter{

	//過濾器的銷燬方法
	public void destroy() {
		System.out.println("過濾銷燬");
	}

	//過濾器的主方法
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		request.setCharacterEncoding("utf-8");
		
		//過濾的開始攔截
		System.out.println("請求的攔截 ");
		
		//使用裝飾者的類進行加強,可以進行方法加強的過濾
		MyServlet myrequest = new MyServlet(request);
		
		//放行,執行過濾完了以後的後面的邏輯,或者是執行過濾鏈中的其他過濾
		chain.doFilter(myrequest,resp);
		
		//過濾後的執行
		System.out.println("響應的攔截");
		
	}

	//過濾器的初始化
	public void init(FilterConfig config) throws ServletException {
		//通過FilterConfig的物件可以得到在web.xml中對過濾器的配置屬性
		String encoding = config.getInitParameter("encoding");
		
		System.out.println(encoding);
		System.out.println("過濾的初始化");
	}

}

/**
* 當要對一個類中的方法進行改造和加強,可以使用裝飾者模式
*/

class MyServlet extends HttpServletRequestWrapper{
	//1)要設定一個成員變數用來進行設定
	private HttpServletRequest request;
	
	public MyServlet(HttpServletRequest request) {
		super(request);
		//2)在有參的構造方法中進行對成員變數的設定
		this.request = request;
	}
	
	//3)重寫要進行加強的方法
	@Override
	public String getParameter(String name) {
		try {
			//1)得到原來的實際引數內容
			String value = request.getParameter(name);//iso-8859-1
			//2)增強
			if(value!=null && "GET".equals(request.getMethod())){
				value = new String(value.getBytes("iso-8859-1"),"utf-8");
			}
			//3)返回增強後內容
			return value;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		
	}
	
	@Override
	public String[] getParameterValues(String name) {
		try {
			String[] values = request.getParameterValues(name);
			if(values!=null && "GET".equals(request.getMethod())){
				for(int i=0;i<values.length;i++){
					values[i] = new String(values[i].getBytes("iso-8859-1"),"utf-8");
				}
			}
			return values;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
}

然後在web.xml中進行配置
<?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">
  <display-name></display-name>
  
  <!-- 設定了過濾器之後要在web.xml中進行配置,過濾鏈中過濾的順序主要看filter-mapping的順序 -->
  <filter>
 	<filter-name>demo4</filter-name>
 	<filter-class>c_example_filter.demo1</filter-class>
 	<!-- 在過濾器中也可以進行引數的配置 -->
 	<init-param>
 		<param-name>encoding</param-name>
 		<param-value>xxx</param-value>
 	</init-param>
 </filter>
 <filter-mapping>
 	<!--dispatcher的屬性,error表示當頁面是錯誤的時候進行過濾
 		forward表示當頁面有轉發的語句,可以設定對轉發的頁面進行過濾
 		include表示當頁面有包含的語句,要過濾是可以設定對包含的頁面進行過濾
 		request表示頁面就是普通的頁面,既沒有轉發也沒有包含和錯誤,直接進行過濾,預設為request
 	  -->
 	<filter-name>demo4</filter-name>
 	<url-pattern>/demo1</url-pattern>
 	<dispatcher>ERROR</dispatcher>
 	<dispatcher>FORWARD</dispatcher>
 	<dispatcher>INCLUDE</dispatcher>
 	<dispatcher>REQUEST</dispatcher>
 </filter-mapping>
</web-app>
然後在servlet的處理前就會先走過濾器了
<pre name="code" class="java">package c_example_filter;

import java.io.IOException;
import java.util.Arrays;

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

public class Cdemo1 extends HttpServlet {

	private static final long serialVersionUID = 1L;

	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//得到的資料可以通過過濾器把程式碼進行解碼
		String name = request.getParameter("name");
		String[] names = request.getParameterValues("name");
		System.out.println(Arrays.asList(names));
		System.out.println(name);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}


今天把一個過濾器學習完了,能夠在很多的應用場景中運用的上
過濾器的原理圖:
<img src="https://img-blog.csdn.net/20160807001033357?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
<img src="https://img-blog.csdn.net/20160807001036998?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />