JSP/Servlet及相關技術詳解(三)

2.12 Filter介紹
使用Filter完整的流程:Filter對用戶請求進行預處理,接着將請求交給Servlet進行處理並生成響應,最後
Filter再對服務器響應進行後處理。
用處:
1.在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest.
2.根據需要檢查HttpServletRequest,也可以修改HttpServletRequest頭和數據。
3.在HttpServletResponse到達客戶端之前,攔截HttpServletResponse.
4.根據需要HttpServletResponse,也可以修改HttpServletResponse頭和數據。

種類:
用戶授權的Filter:Filter負責檢查用戶請求,根據請求過濾用戶非法請求。
日誌Filter:詳細記錄某些特殊的用戶請求。
負責解碼的Filter:包括對非標準編碼的請求編碼。
能改變XML內容的XSLT Filter等
Filter可負責攔截多個請求或響應;一個請求或響應也可被多個Filter攔截。

步驟:
創建Filter處理類。
web.xml文件中配置Filter.

2.12.1 創建Filter類
創建Filter必須實現javax.servlet.Filter接口。
> void init(FilterConfig config);
> void destroy();
> void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);

ex:
@WebFilter(filtName="log", urlPatterns={"/*"})
public class LogFilter implements Filter{
   //FilterConfig可用於訪問Filter的配置信息
   private FilterConfig config;
   //實現初始化方法
   public void init(FilterConfig config){
       this.config = config;
   }
   //實現銷燬方法
   public void destroy(){
       this.config = null;
   }
   //執行過濾的核心方法
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throw IOException, ServletExceptioin{
       //----下面代碼用於對用戶請求執行預處理----
       //獲取ServletContext對象,用於記錄日誌
       ServletContext context = this.config.getServletContext();
       long before = System.currentTimeMillis();
       //將請求轉換成HttpServletRequest請求
       HttpServletRequest hrequest = (HttpServletRequest)request;
       //輸出提示信息
       System.out.println("Filter已經截獲到用戶的請求的地址: "+
                          hrequest.getServletPath());
       //Filter只是鏈式處理,請求依然放行到目的地址
       chain.doFilter(request, response);
       //----下面代碼用於對服務器響應執行後處理----
       long after =  System.currentTimeMillis();
       //輸出提示信息
       System.out.println("過濾結束");
       //輸出提示信息
       System.out.println("請求被定位到"+hrequest.getRequestURI()+" 所花的時間爲:
                           "+(after-before));
   }
}

2.12.2 配置Filter
配置兩個部分:
>配置Filter名
>配置Filter攔截URL模式。

配置可以使用兩種方式:
>在Filter類中通過Annotation進行配置
>在web.xml文件中通過配置文件進行配置

@WebFilter常用屬性:
asyncSupported
dispatchTypes
displayName
filterName
initParams
servletNames
urlPatterns/value

web.xml:
<filter>
   <filter-name>log</filter-name>
   <filter-class>lee.LogFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>log</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

2.12.3 使用URL Rewrite實現網站僞靜態
可以通過Filter攔截所有發向*.html請求,然後按某種規則將請求forward到實際的*.jsp頁面即可。
具體信息參考http://tuckey.org/urlrewrite/

2.13 Listener介紹
ServletAPI提供了大量監聽器來監聽Web應用的內部事件,從而允許Web內部事件發生時回調事件監聽器內的方法。
步驟:
定義Listener實現類。
通過Annotation或在web.xml文件中配置Listener.

2.13.1 實現Listener類
Web事件監聽器接口:
ServletContextListener:監聽Web應用的啓動和關閉
ServletContextAttributeListener:application範圍內屬性的變化
ServletRequestListener:監聽用戶請求
ServletRequestAttributeListener:監聽request內屬性的改變
HttpSessionListener:監聽用戶session的開始和結束
HttpSessionAttributeListener:監聽session範圍內屬性的變化

ServletContextListener:
contextInitialized(ServletContextEvent sce);
contextDestroyed(ServletContextEvent sce);

2.13.2 配置Listener
方式:
使用@WebListener修飾Listener實現類即可。
在web.xml文檔中使用<listener.../>元素進行配置。

<listener>
   <listener-class>lee.GetConnListener</listener-class>
</listener>

2.13.3 使用ServletContextAttributeListener
attributeAdded(ServletContextAttributeEvent event);
attributeRemoved(ServletContextAttributeEvent event);
attributeReplaced(ServletContextAttributeEvent event);

2.13.4 使用ServletRequestListener和ServletRequestAttributeListener
ServletRequestListener:
requestInitialized(ServletRequestEvent sre);
requestDestroyed(ServletRequestEvent sre);

ServletRequestAttributeListener:
attributeAdded(ServletRequestAttributeEvent event);
attributeRemoved(ServletRequestAttributeEvent event);
attributeReplaced(ServletRequestAttributeEvent event);

2.13.5 使用HttpSessionListener和HttpSessionAttributeListener
HttpSessionListener:
sessionCreated(HttpSessionEvent se);
sessionDestroyed(HttpSessionEvent se);

HttpSessionAttributeListener:
attributeAdded
attributeRemoved
attributeReplaced

2.14 JSP2特性
新特性:
直接配置JSP屬性
表達式語言
簡化的自定義標籤API
Tag文件語法

2.14.1 配置JSP屬性
<jsp-property-group/>
是否允許使用表達式語法:<el-ignored/>
是否允許使用JSP腳本:<script-invalid/>
聲明JSP頁面的編碼:<page-encoding/>
使用隱式包含:<include-prelude/>和<include-coda/>
ex:
<?xml version="1.0" encoding="GBK"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   version="3.0">
   <!-- 關於JSP的配置信息 -->
   <jsp-config>
       <jsp-property-group>
           <!-- 對哪些文件應用配置 -->
           <url-pattern>/noscript/*</url-pattern>
           <!-- 忽略表達式語法 -->
           <el-ignored>true</el-ignored>
           <!-- 頁面編碼的字符集 -->
           <page-encoding>GBK</page-encoding>
           <!-- 不允許使用java腳本 -->
           <scripting-invalid>true</scripting-invalid>
           <!-- 隱式導入頁面頭  -->
           <include-prelude>/inc/top.jspf</include-prelude>
           <!-- 隱式導入頁面尾 -->
           <include-coda>/inc/bottom.jspf</include-coda>
       </jsp-property-group>
       <jsp-property-group>
           <!-- 對哪些文件應用配置 -->
           <url-pattern>*.jsp</url-pattern>
           <el-ignored>false</el-ignored>
           <!-- 頁面編碼字符集 -->
           <page-encoding>GBK</page-encoding>
           <!-- 允許使用java腳本 -->            
           <scripting-invalid>false</scripting-invalid>
       </jsp-property-group>
       <jsp-property-group>
           <!-- 對哪些文件應用配置 -->
           <url-pattern>/inc/*</url-pattern>
           <el-ignored>false</el-ignored>
           <!-- 頁面編碼字符集 -->
           <page-encoding>GBK</page-encoding>
           <scripting-invalid>true</scripting-invalid>
       </jsp-property-group>
   </jsp-config>

   <context-param>
       <param-name>author</param-name>
       <param-value>yeeku</param-value>
   </context-param>

</web-app>

2.14.2 表達式語言
數據訪問語言
${expression}
1.表達式語言支持的算術運算符和邏輯運算符
+-*/% div mod == ?:
< lt > gt >= ge <= le == eq != ne
2.表達式的內置對象
pageContext:代表該頁面的pageContext對象
pageScope:用於獲取page範圍的屬性值
requestScope:用於獲取request範圍的屬性值
sessionScope:用於獲取session範圍的屬性值
applicationScope:用於獲取application範圍的屬性值
param:用於獲取請求的參數值
paramValues:獲取屬性值爲數組的屬性值
header:用於獲取請求頭的屬性值
headerValues:獲取屬性值爲數組的屬性值
initParam:用於獲取請求Web應用的初始化參數
cookie:用於獲取指定的Cookie值

3.表達式語言的自定義函數
開發步驟:
>開發函數處理類:若干個靜態方法,每個靜態方法可以定義爲一個函數
public class Function{
   public static String reverse(String text){
       return new StringBuffer(text).reverse().toString().  
   }
   public static int countChar(String text){
       return text.length();
   }
}
>使用標籤庫定義函數:
ex:
<function>
   <name>reverse</name>
   <function-class>lee.Functions</function-class>
   <function-signature>java.lang.String reverse(java.lang.String)</function-signature>
</function>
>在JSP頁面的EL中使用函數:
<%@taglib prefix="crazyit" uri="http://www.crazy.org/tags"%>
${crazyit:reverse(param["name"])}

整個過程類似於自定義標籤。

2.14.3 Tag File支持
TagFile是自定義標籤的簡化用法,使用Tag File可以無須定義標籤處理類和標籤庫文件,但仍然可以在JSP頁面中
使用自定義標籤。
建立一個迭代器標籤步驟:
1.建立Tag文件,格式類似於JSP文件。
Tag File具有5個指令:
taglib:導入其他標籤庫
include:導入其他JSP或者靜態頁面
tag:類似於JSP中的page指令
attribute:標籤屬性
variable:設置自定義標籤的變量,這些變量傳給JSP頁面使用。
ex:
<%@ tag pageEncoding="GBK" import="java.util.List" %>
<%@ attribute name="bgColor"%>
<%@ attribute name="cellColor" %>
<%@ attribute name="title" %>
<%@ attribute name="bean" %>
<table border="1" bgcolor="${bgColor}">
<tr>
<td><b>${title}</b></td>
</tr>
<% List<String> list=(List<String>)request.getAttribute("a");
  for(Object ele : list) { %>
  <tr>
  <td bgcolor="${cellColor}" >
  <%=ele%>
  </td>
  </tr>
<%}%>
</table>

2.在頁面中使用自定義標籤是,需先導入標籤庫,在使用標籤。
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
</tags:iterator bgColor="#99dd99" cellColor="#9999cc"
               title="迭代器標籤" bean="a" />

Tag File只有以下內置對象:
request
response
session
application
config
out

2.15 Servlet 3.0新特性
2.15.1 Servlet3.0的Annotation
@WebServlet
@WebInitParam
@WebListener
@WebFilter
@MultipartConfig:修飾Servlet,指定Servlet將會負責處理multipart/form-data類型的請求(主要用於文件上傳)
@ServletSecurity:JAAS,安全與授權控制
@HttpConstraint:和ServletSecurity一起使用。
@HttpMethodConstraint:和ServletSecurity一起使用。

2.15.2 Servlet3.0的Web模塊支持
<webModule>.jar
   |--META-INFO
   |      |--web-fragment.xml
   |--Web模塊所用的類文件、資源文件等。
web-fragment.xml文件:
<name.../>:指定Web模塊的名稱
<ordering.../>:用於指定加載Web模塊的相對順序

2.15.3 Servlet3.0提供的異步處理
Servlet3.0的異步處理是通過AsyncContext類來處理的,Servlet可通過ServletRequest的如下兩個方法開啓異步
調用、創建AsyncContext對象。
AsyncContext startAsync()
AsyncContext startAsync(ServletRequest, ServletResponse);

ex:
@WebServlet(urlPatterns="/async", asyncSupported=true)

AsyncContext actx = request.startAsync();
actx.setTimeout(30*1000);
actx.start(new Execute(actx));

當Servlet啓動異步調用的線程之後,該線程的執行對開發者是透明的。
可藉助AyncListener來監聽。
onStartAsync(AsyncEvent event);
onComplete(AsyncEvent event);
onError(AysncEvent event);
onTimeout(AsyncEvent event);
註冊使用:
actx.addListener(new MyAsyncListener());

2.15.4 改進的Servlet API
1.HttpServletRequest增加了對文件上傳的支持。
Part getPart(String name)
Collection<Part> getParts()
表單結構:
<form method="post" action="upload" enctype="multipart/form-data">
文件名:<input type="text" id="name" name="name"/><br/>
選擇文件:<input type="file" id="file" name="file"/><br/>
<input type="submit" value="上傳"/><br/>
</form>

2.ServletContext允許通過編程的方式動態註冊Servlet、Filter。
ServletContext提供瞭如下方法來動態的註冊Servlet, Filter, 並允許動態設置Web應用的初始化參數。
addServlet
addFilter
addListener
setInitParameter(String name, String value)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章