概念:由java編寫的,線程安全的web組件,完成請求攔截和結果攔截
主要作用:作爲控制層組件、請求攔截(編碼攔截器、請求驗證攔截器、非法文字攔截器)
結果攔截(懶加載攔截器)
語法:
1 包聲明
2 包導入
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.*;
3 包定義(實現Filter接口)
4 實現Filter接口的三個方法
public void init(FilterConfig filterConfig)
throwsServletException{}
//請求被攔截器攔截到就調用
public void doFilter(ServletRequest req,
ServletResponse resp,FilterChain chain)
throws IOException,ServletException{
//造型,使request,response 擁有http特徵
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
System.out.println("** 過濾器 doFilter (chain之前)...") ;
//一旦第一個攔截器通過,若還有攔截器,激活下一個攔截器,沒有則請求下傳
//如果將此語句註釋,會導致所有請求都被攔截,不能下傳
chain.doFilter(request,response) ;
System.out.println("** 過濾器 doFilter (chain之後)...") ;
}
public void destroy(){}
部署:打包編譯
配置(/* 對所有的請求都攔截):
<filter>
<filter-name>first</filter-name>
<filter-class>cn.mldn.lxh.filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>first</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
編碼攔截
請求攔截
只能處理用戶表單裏發送的漢字
語法
包聲明
包導入
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.*;
類名和文件名相同,實現Filter接口;
實現Filter接口的所有方法
public void init(FilterConfig filterConfig) throws ServletException
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//request.setCharacterEncoding("GB2312") ;// 寫死了,不夠靈活,不推薦使用
request.setCharacterEncoding(this.encoding) ; // 通過配置信息獲取編碼,非常靈活
chain.doFilter(request,response) ; // 將請求下傳
}
public void destroy()
部署:打包編譯
配置(對所有的請求都攔截):
<filter>
<filter-name>encodingfilter</filter-name>
<filter-class>cn.mldn.lxh.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
請求驗證攔截器
請求攔截
原理
對某一類請求進行攔截,當請求來了 tomcat把請求交給攔截器,調用doFilter方法,調用session查看是否有驗證信息,若沒有就直接跳轉到登陸界面,若有就進入首頁;
實例代碼:
String currentURL = request.getRequestURL(); //currentURL = /kkkk/xxxx.jsp;
String targetURL = currentURL.substring(currentURL.indexOf("/",1)); // targetURL = /xxxx.jsp;
//如果有session就返回session,否則返回NULL,默認爲false
HttpSession session = request.getSession(false); //若爲true:沒取到session就創建一個session
if(!"/index.jsp".equals(tragetURL)){
if(session==null||session.getAttribute("name")==null){ //短路或,見真就爲真,看到前 面爲真就不執行後面的代碼
System.out.println("request.gatContextPath()="+
request.gatContextPath()); //request.gatContextPath()=/kkkk
response.sendRedirect(request.getContextPath()+ "/index.jsp") // 服務端跳至/kkkk/index.jsp 服務端跳轉不經過攔截器
return;
}
}
//請求下傳
chain.doFilter(request,response);
過程
從request裏獲取請求字符串"/kkkk/xxxx.jsp",截取子串"/xxxx.jsp"作爲目標字符串,比較目標字符串是否與"/index.jsp"一致;
若一致,判斷是否有用戶的session信息,若沒有,跳轉到登錄頁面,若有就將請求下傳;
若不一致,直接將請求下傳;
非法文字攔截器
請求攔截
只要出現指定的非法文字,就會自動跳轉到出錯頁面,或者顯示非法文字提醒;
String content = request.getParameter("content") ;
//判斷是否爲NULL,是NULL直接請求下傳
if(content!=null)
{
// 如果indexOf返回-1則表示沒有查到所要的內容
if(content.indexOf("你XX")==-1)
{
chain.doFilter(req,resp) ;
}
else
{
resp.sendRedirect("error.jsp");
System.out.println("有非法文字") ;
// 如果需要的話,此處依然可以使用RequestDispatcher進行跳轉
}
}
else
{
chain.doFilter(request,response) ;
}
懶加載攔截器
結果攔截
懶加載(簡單瞭解)
是Hibernate爲提高程序執行效率而提供的一種機制,即只有真正使用該對象的數據時纔會創建。
Hibernate中主要是通過代理(proxy)機制來實現延遲加載。它的具體過程:Hibernate叢數據庫獲取某一個對象數據時、獲取某一個對象的集合屬性值時,或獲取某一個對象所關聯的另一個對象時,由於沒有使用該對象的數據,hibernate並不是數據庫加載真正的數據,而只是爲該對象創建一個代理對象來代表這個對象,這個對象上的所有屬性都是默認值;只有在真正需要使用該對象的數據時才創建這個真實對象,真正從數據庫中加載它的數據,這樣在某些情況下,就可以提高查詢效率。
實例:
User user=(User)session.load(class, id); // 直接返回的是代理對象
System.out.println(user.getId()); // 沒有發送sql語句到數據庫加載
user.getName(); // 創建真實的User實例,併發送sql語句到數據庫中
懶加載攔截器
異常原因
Hibernate 允許對關聯對象、屬性進行延遲加載,但是必須保證延遲加載的操作限於同一個 Hibernate Session 範圍之內進行。如果 Service 層返回一個啓用了延遲加載功能的領域對象給 Web 層,當 Web 層訪問到那些需要延遲加載的數據時,由於加載領域對象的 Hibernate Session 已經關閉,這些導致延遲加載數據的訪問異常。
解決
使用"Open Session in View"的模式;
連接要在結果信息即將回到瀏覽器之前才關閉;
所以攔截器就是要在結果回到瀏覽器之前,對連接進行關閉的操作;
攔截器可以作爲第三方的插件,插入項目中;
web請求大致流程:攔截器--->servlet--->jsp--->攔截器,所以servlet不適合做攔截器,因爲結果最後從jsp傳出去,不經過servlet;