Java EE 基礎知識學習(六)
這一部分我們要介紹Java EE中的Filter。
Filter可以對使用者的請求進行預處理,同時也可以對HttpServletResponse進行後處理,是一個典型的處理鏈,所以Filter也叫做攔截器。Filter也可以像Servlet一樣對使用者的請求做出響應,但一般我們都會使用Servlet來響應使用者,而不是用Filer。
使用Filter的好處:
- Filter可以在HttpServletRequest到達Servlet之前,攔截HttpServletRequest
- Filter可以檢查HttpServletRequest,並且修改HttpServletRequest
- 可以在HttpServletResponse到達客戶端之前,攔截HttpServletResponse
- Filter可以檢查HttpServletResponse,並且修改HttpServletResponse
總結起來,Filter可以幫助我們在使用者的請求訪問Servlet之前,攔截使用者的請求並做出修改,同時也可以幫助我們在伺服器的響應到達使用者客戶端之前,攔截響應並且做出響應的修改。
Filter的種類:
- 使用者授權的Filter:負責檢查使用者請求並且過濾非法請求
- 日誌Filter:用來記錄使用者的請求和伺服器的響應
- 能改變XML內容的XSLT Filter等
- 負責解碼的Filter:改變響應和請求的編碼
- Filter負責攔截多個請求或者響應
建立Filter的步驟:
- 建立一個Filter處理類
- 配置Filter
建立一個Filter處理類就是寫好一個類,並且繼承Filter,然後在其中的doFilter方法中編寫你的Filter所要做的事情。
配置Filter有兩種方式,一種方式是在web.xml檔案中配置,一種是使用源註解來配置。
下面是一個改變編碼的Filter類,它接收到使用者的請求或者接收到伺服器的響應會對請求或者響應改變他們的編碼:
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;
/**
* Servlet Filter implementation class EncodingFilter
*/
@WebFilter(filterName="encodingFilter",urlPatterns={"/*"})
public class EncodingFilter implements Filter {
/**
* Default constructor.
*/
public EncodingFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
private String str="UTF-8";
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
request.setCharacterEncoding(str);
response.setCharacterEncoding(str);
// pass the request along the filter chain
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
在上面的Filter中我們使用了源註解來配置Filter,我們只需要在類程式碼段的上面加入下面程式碼即可:
@WebFilter(filterName="encodingFilter",urlPatterns={"/*"})
上面的程式碼中urlPatterns表示我們要攔截的使用者請求或者響應的url,“/*”表示攔截一切請求或者響應。
或者我們可以在web.xml中加入下面程式碼來配置Servlet:
<filter>
<!--Filter的名字,相當於@WebFilter中的filterName屬性-->
<filter-name>encodingFilter</filter-name>
<!--Filter實現類-->
<filter-class>EncodingFilter</filter-class>
</filter>
<filter-mapping>
<!--Filter名字-->
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter的幾個示例:
日誌Filter:在這裡我們編寫一個記錄使用者請求的Filter,程式碼如下:
package com.example;
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;
import javax.servlet.http.HttpServletRequest;
/**
* Servlet Filter implementation class Test
*/
@WebFilter("/*")
public class Test implements Filter {
/**
* Default constructor.
*/
public Test() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
System.out.println(request.getRemoteAddr());//輸出使用者ip地址
HttpServletRequest hreq=(HttpServletRequest)request;
System.out.println(hreq.getRequestURI());//輸出使用者的請求地址
// pass the request along the filter chain
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
攔截未登入使用者:大部分web頁面我們都需要使用者登入才可以訪問,而沒有登入的我們將讓頁面跳轉到登入頁面,讓使用者登入,下面的Filter實現的就是這樣的功能,程式碼如下:
package com.example;
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* Servlet Filter implementation class Test
*/
@WebFilter("/*")
public class Test implements Filter {
/**
* Default constructor.
*/
public Test() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
HttpServletRequest hreq=(HttpServletRequest)request;
HttpSession session=hreq.getSession();
String path=hreq.getServletPath();
String loginPage="/login.jsp";
String proLogin="/proLogin.jsp";
if(session.getAttribute("user")==null&&!path.endsWith(loginPage)&&!path.endsWith(proLogin))
{
request.getRequestDispatcher(loginPage).forward(request, response);
}
else{
// pass the request along the filter chain
chain.doFilter(request, response);
}
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
在上面的程式碼中我們的判斷語句有三個條件:
- 使用者沒有登入
- 使用者當前不在登入頁面
- 使用者當前不在處理登入的頁面
剛開始編寫這個Filter的時候,很多人可能認為我們只需要判斷使用者有沒有登入就好,如果沒有登入就跳轉到登入頁面就可以了,但是如果你真的這樣做了你的程式可能會報錯,比如使用者沒有登入然後跳轉到了登入頁面,然後使用者輸入使用者名稱和密碼並且點選了登入,這時候程式會有兩個動作,一個是你的登入頁面寫的當使用者登入成功後要跳轉到一定的頁面,另一個動作是請求被Filter攔截了,這時候Filter也有一個當使用者已經登入的時候做的跳轉,導致的結果就是你的程式同一時間出現了兩個跳轉,程式就會報錯,所以我們必須要有下面的兩個條件,這樣才不會導致上述錯誤的發生。
相關文章
- 別樣JAVA學習(一)基礎知識Java
- 【ASM學習】基礎知識ASM
- Java基礎知識學習筆記總結Java筆記
- Android基礎知識學習Android
- 基礎知識學習筆記筆記
- JavaSE基礎知識學習-----集合Java
- WebAPI基礎知識學習(1)WebAPI
- 【ASM學習】ASM基礎知識ASM
- Java基礎知識回顧之六 —– IO流Java
- Java基礎知識回顧之六 ----- IO流Java
- JavaSE基礎知識分享(六)Java
- WiFi基礎(六):天線基礎知識WiFi
- Java基礎複習,整理知識點Java
- Java基礎知識Java
- 學習Java知識應該注意哪些基礎原則Java
- 初識Java Java基礎知識Java
- JavaSE基礎知識學習—–多型Java多型
- JavaSE基礎學習知識整理大全Java
- RxJava 學習筆記 -- 基礎知識RxJava筆記
- JVM學習之JVM基礎知識JVM
- 怎麼學習基礎知識啊?
- JavaSE基礎知識學習-----多型Java多型
- JavaSE基礎知識學習-----Object類JavaObject
- JavaSE基礎知識學習-----繼承Java繼承
- go語言學習-基礎知識Go
- 六西格瑪的基礎知識
- 零基礎學習Java,全方位知識點總結!Java
- 學習Java基礎知識,打通面試關~十三鎖機制Java面試
- Java基礎概念知識Java
- java基礎知識點Java
- Java基礎知識(二)Java
- Java SE 基礎知識Java
- java培訓基礎知識都學哪些Java
- iOS 基礎知識學習目錄索引iOS索引
- Android 動畫基礎知識學習(下)Android動畫
- Docker容器學習梳理 - 基礎知識(2)Docker
- Docker容器學習梳理–基礎知識(2)Docker
- linux基礎知識學習筆記Linux筆記