過濾器
過濾器是處於客戶端與服務器資源文件之間的一道過濾網,在訪問資源文件以前,經過一系列的過濾器對請求進行修改、判斷等,把不符合規則的請求在中途攔截或修改。也能夠對響應進行過濾,攔截或修改響應。
以下圖,瀏覽器發出的請求先遞交給第一個filter進行過濾,符合規則則放行,遞交給filter鏈中的下一個過濾器進行過濾。過濾器在鏈中的順序與它在web.xml中配置的順序有關,配置在前的則位於鏈的前端。當請求經過了鏈中全部過濾器後就能夠訪問資源文件了,若是不能經過,則可能在中間某個過濾器中被處理掉。
過濾器通常用於登陸權限驗證、資源訪問權限控制、敏感詞彙過濾、字符編碼轉換等等操做,便於代碼的重用,沒必要每一個servlet中還要進行相應的操做。
過濾器的簡單應用:
一、新建一個class,實現接口Filter(注意:是javax.servlet中的Filter)。
二、重寫過濾器的doFilter(request,response,chain)方法。另外兩個init()、destroy()方法通常不須要重寫。在doFilter方法中進行過濾操做。
三、在web.xml中配置過濾器。這裏要謹記一條原則:在web.xml中,監聽器>過濾器>servlet。也就是說web.xml中監聽器配置在過濾器以前,過濾器配置在servlet以前,不然會出錯。
<filter>
<filter-name>loginFilter</filter-name>//過濾器名稱
<filter-class>com.nnngu.filter.loginFilter</filter-class>//過濾器類的包路徑
<init—param> //可選
<param—name>參數名</param-name>//過濾器初始化參數
<param-value>參數值</param-value>
</init—pamm>
</filter>
<filter-mapping>//過濾器映射
<filter-name>loginFilter</filter-name>
<url—pattern>指定過濾器做用的範圍</url-pattern>
</filter-mapping>
<url-pattren>處定義過濾器做用的範圍。通常有如下規則:
一、做用與全部web資源:<url—pattern>/</url-pattern>。則客戶端請求訪問任意資源文件時都要通過過濾器的過濾,經過則能夠訪問,不然不能訪問。
二、做用於某一文件夾下全部文件:<url—pattern>/dir/</url-pattern>
三、做用於某一種類型的文件:<url—pattern>.擴展名</url-pattern>。好比<url—pattern>.jsp</url-pattern>過濾全部對jsp文件的訪問請求。
四、做用於AxiTrader返傭www.fx61.com/brokerlist/axitrader.html某一文件夾下某一類型文件:<url—pattern>/dir/.擴展名</url-pattern>
若是一個過濾器須要過濾多種文件,則能夠配置多個<filter-mapping>,一個mapping定義一個url-pattern來定義過濾規則。以下:
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.nnngu.filter.loginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
例1:用過濾器實現登陸驗證,沒登陸則駁回訪問請求並重定向到登陸頁面。
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest) arg0;
HttpServletResponse response=(HttpServletResponse) arg1;
HttpSession session=request.getSession();
String path=request.getRequestURI();
Integer uid=(Integer)session.getAttribute("userid");
if(path.indexOf("/login.jsp")>-1){//登陸頁面不過濾
arg2.doFilter(arg0, arg1);//遞交給下一個過濾器
return;
}
if(path.indexOf("/register.jsp")>-1){//註冊頁面不過濾
arg2.doFilter(request, response);
return;
}
if(uid!=null){//已經登陸
arg2.doFilter(request, response);//放行,遞交給下一個過濾器
}else{
response.sendRedirect("login.jsp");
}
}
例2:設置字符編碼
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request2=(HttpServletRequest) request;
HttpServletResponse response2=(HttpServletResponse) response;
request2.setCharacterEncoding("UTF-8");
response2.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
建立Filter
建立一個類而後實現Filter
注意:
導入的包是javax.servlet.Filter下的包
初始化init是再啓動tomcat的時候進行初始化的
doFilter中的chain.doFilter是放行的方法
建議把doFilter中的request和response轉換爲帶協議的HttpServletRequset和HttpServletResponse
由於帶協議的Http是不帶協議的子類,裏面的方法比父類更豐富,方便後面調用方法
下面是建立Filter的實例代碼
package cn._02FilterChain;
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.annotation.WebFilter;br/>@WebFilter("/chain")
public class AFilter implements Filter{br/>@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stubbr/>}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse) response;
System.out.println("A放行以前+++");
chain.doFilter(req, resp);}
@Override
br/>System.out.println("A放行以後---");
}
@Override
public void destroy() {
// TODO Auto-generated method stubbr/>}
}
Filter再web.xml中的配置
配置方式有
1.再web.xml中進行配置
2.再類中加上@WebFilter("攔截路徑");
filter鏈式的執行方式
調用方式是按照配置的<filter-mapping>來調用的
下面是web.xml的實例代碼
<filter>
<filter-name>chainA</filter-name>
<filter-class>cn._02FilterChain.AFilter</filter-class>
</filter>
<filter>
<filter-name>chainB</filter-name>
<filter-class>cn._02FilterChain.BFilter</filter-class>
</filter>
<filter>
<filter-name>chainC</filter-name>
<filter-class>cn._02FilterChain.CFilter</filter-class>
</filter>
<!-- 執行順序按照filter-mapping執行 -->
<filter-mapping>
<filter-name>chainB</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>chainA</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>chainC</filter-name>
<url-pattern>/chain</url-pattern>
</filter-mapping>
package com.zzxtit.common.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 CharacterEncodingFilter implements Filter{
private static String encoding = "UTF-8";
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding") == null ? "UTF-8" : filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding(encoding);
}
}
注 :
(1)使用getInitPamater是從web.xml裏獲取變量enciding的默認值
(2)chain的做用 :通常filter都是一個鏈,web.xml裏配置了幾個就有幾個。一個一個連在一塊兒,chain.doFilter()將請求轉發給過濾器鏈下一個filter
代碼實現
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.zzxtit.common.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>html