1. 程式人生 > >Java Filter學習

Java Filter學習

filter作用解決全域性亂碼 對目標資源進行預前處理

函式 作用 生命週期
init(FilterConfig) filter物件初始化時執行(filter物件初始化方法 只執行一次)
doFilter(ServletRequest,ServletResponse,FilterChain) filter過濾器核心方法(每次訪問到要過濾的資源都會執行)
destory() filter物件銷燬時方法(filter物件銷燬時方法 只執行一次)
<!--在web.xml中配置filter-->
<filter>
	<filter-name>test</filter-name>
	<filter-class>com.java.Test</filter-class>
	<init-param>
		<param-name>url</param-name>
		<param-value>www.baidu.com</param-value>
	</init-param>
</filter> <filter-mapping> <filter-name>test</filter-name> //<url-pattern>/test</url-pattern>--過濾資源路徑為 專案名/test的請求 //<url-pattern>*.abc</url-pattern>--過濾資源路徑所有後綴為abc的請求 //<url-pattern>/a/b/c/*</url-pattern>--過濾資源路徑字首為 專案名/a/b/c的所有請求 //<url-pattern>/a/b/c/*.abc</
url-pattern
>
--不可混用 此處錯誤示範 <url-pattern>/*</url-pattern>--一般用法 當前為過濾所有路徑 //<servlet-name>abc</servlet-name> <dispatcher>REQUEST</dispatcher>--預設值 直接訪問某個資源才能執行該過濾器方法 直接訪問執行一次 sendRedirect訪問執行兩次 //<dispatcher>FORWARD</dispatcher>-- 轉發訪問某個資源才能執行該過濾器方法 forward()方法執行後呼叫 後執行filter //<dispatcher>INCLUDE</dispatcher>-- A資源包含B資源訪問某個資源才能執行該過濾器方法 //<dispatcher>ERROR</dispatcher>-- 出錯後 訪問某個資源才能執行該過濾器方法 </filter-mapping>
public class Test implements Filter {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
	FilterChain chain) throws IOException, ServletException {
		System.out.println("Hello Filter");
		chain.doFilter(request, response);//代表放行 不放行無法執行下一步的servlet方法
	}

	@Override
	public void init(FilterConfig filterConfig)//當前filter的配置物件
	throws ServletException {
		String name = filterConfig.getFilterName();//獲取web.xml<filter-name>的文字節點
		String test = filterConfig.getInitParameter("url");
		ServletContext context = filterConfig.getServletContext();
		//ServletContext context = this.getServletContext();--一般用這種方式獲取
	}
}

FilterChain(過濾器鏈)物件維護著該filter物件的索引 連線多個filter 控制執行和執行順序

過濾器可以多個連結到一起過濾 所有filter都要放行才可訪問目標資源
filter可以用許可權控制 連線資料庫獲取值後判斷許可權大小決定是否放行
/*
 * 使用filter解決亂碼
 * 使用裝飾著設計模式
*/
public class EncodingFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
 
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		 //轉型為與協議相關物件
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		 //對request包裝增強
		HttpServletRequest myrequest = new MyRequest(httpServletRequest);
		chain.doFilter(myrequest, response);
	}
 
	@Override
	public void destroy() {
	}
 
}
 
//自定義request物件
class MyRequest extends HttpServletRequestWrapper {
 
	private HttpServletRequest request;
 
	private boolean hasEncode;
 
	public MyRequest(HttpServletRequest request) {
		super(request);//super必須寫
		this.request = request;
	}
 
		//對需要增強方法 進行重寫覆蓋
	@Override
	public Map getParameterMap() {
		 //先獲得請求方式
		String method = request.getMethod();
		if (method.equalsIgnoreCase("post")) {
		 //post請求
		try {
			//處理post亂碼
		request.setCharacterEncoding("utf-8");
				return request.getParameterMap();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		} else if (method.equalsIgnoreCase("get")) {//tomcat8.5已經處理了get中文可以將get中的程式碼註釋掉
			 //get請求
			Map<String, String[]> parameterMap = request.getParameterMap();
			if (!hasEncode) {//確保get手動編碼邏輯只執行一次
				for (String parameterName : parameterMap.keySet()) {
					String[] values = parameterMap.get(parameterName);
					if (values != null) {
						for (int i = 0; i < values.length; i++) {
							try {
								 //處理get亂碼
								values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
							} catch (UnsupportedEncodingException e) {
								e.printStackTrace();
								}
							}
						}
					}
				hasEncode = true;
			}
				return parameterMap;
		}
	 
			return super.getParameterMap();
	}
 
	@Override
	public String getParameter(String name) {
		Map<String, String[]> parameterMap = getParameterMap();
		String[] values = parameterMap.get(name);
		if (values == null) {
			return null;
		}
		return values[0];//取回引數的第一個值
	}
 
	@Override
	public String[] getParameterValues(String name) {
		Map<String, String[]> parameterMap = getParameterMap();
		String[] values = parameterMap.get(name);
		return values;
	}
 
}