Java Filter學習
阿新 • • 發佈:2018-12-30
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;
}
}