首頁(yè)技術(shù)文章正文

WEB前端培訓(xùn)之HttpServletRequestWrapper 用法

更新時(shí)間:2017-05-24 來(lái)源:黑馬程序員web前端培訓(xùn)學(xué)院 瀏覽量:

WEB前端培訓(xùn)之HttpServletRequestWrapper 用法


Servlet規(guī)范中所引入的filter令人心動(dòng)不已,因?yàn)樗肓艘粋€(gè)功能強(qiáng)大的攔截模式。Filter是這樣一種Java對(duì)象,它能在request到達(dá)servlet的服務(wù)方法之前攔截HttpServletRequest對(duì)象,而在服務(wù)方法轉(zhuǎn)移控制后又能攔截HttpServletResponse對(duì)象。你可以使用filter來(lái)實(shí)現(xiàn)特定的任務(wù),比如驗(yàn)證用戶輸入,以及壓縮web內(nèi)容。但你擬富有成效地使用過(guò)濾器的念頭卻被你不能改變HttpServletRequest對(duì)象的參數(shù)的現(xiàn)實(shí)掃了興,因?yàn)閖ava.util.Map所包裝的HttpServletRequest對(duì)象的參數(shù)是不可改變的。這極大地縮減了filter的應(yīng)用范圍。至少在一半的時(shí)間里,你希望可以改變準(zhǔn)備傳送給filter的對(duì)象。如果在HttpServletRequest對(duì)象到達(dá)Struts的action  servlet之前,我們可以通過(guò)一個(gè)filter將用戶輸入的多余空格去掉,難道不是更美妙嗎?這樣的話,你就不必等到在Struts的action表單驗(yàn)證方法中才進(jìn)行這項(xiàng)工作了。 
幸運(yùn)的是,盡管你不能改變不變對(duì)象本身,但你卻可以通過(guò)使用裝飾模式來(lái)改變其狀態(tài)。 
現(xiàn)在,讓我們來(lái)看看,如何編寫自己的HttpServletRequest裝飾類。 

一個(gè)刪除空白字符的Filter 
本節(jié)將以上的理論投入實(shí)際使用,通過(guò)實(shí)現(xiàn)一個(gè)刪除空白字符的filter,來(lái)演示如何使用javax.servlet.http.HttpServletRequestWrapper類來(lái)裝飾HttpServletRequest對(duì)象。在本例中,這個(gè)filter將刪除所傳來(lái)的參數(shù)中多余的空白字符。 
這在許多servlet/JSP應(yīng)用中是很有用的,包括Struts及JavaServer  Faces等應(yīng)用。例如,Struts通過(guò)調(diào)用HttpServletRequest對(duì)象的getParameterValues()對(duì)象來(lái)處理action表單。通過(guò)覆蓋裝飾類中此方法,你可以改變當(dāng)前HttpServletRequest對(duì)象的狀態(tài)。 
要?jiǎng)?chuàng)建HttpServletRequest的裝飾類,你需要繼承HttpServletRequestWrapper并且覆蓋你希望改變的方法。列表5中,MyRequestWrapper類將刪除getParameterValues()方法返回值的多余空白字符。 

列表5:HttpServerletRequest裝飾類 
程序代碼: 
package trimmer.filter; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletRequestWrapper; 

public final class MyRequestWrapper extends HttpServletRequestWrapper { 
public MyRequestWrapper(HttpServletRequest servletRequest) { 
super(servletRequest); 


public String[] getParameterValues(String parameter) { 
String[] results = super.getParameterValues(parameter); 
if (results == null) 
return null; 
int count = results.length; 
String[] trimResults = new String[count]; 
for (int i = 0; i < count; i++) { 
trimResults[i] = results[i].trim(); 

return trimResults; 


列表6演示了如何載獲Http請(qǐng)求并裝飾HttpServletRequest對(duì)象。[i]列表6:刪除空白符的filter 


列表6演示了如何載獲Http請(qǐng)求并裝飾HttpServletRequest對(duì)象。 

[i]列表6:刪除空白符的filter 
程序代碼: 
package trimmer.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; 
import javax.servlet.http.HttpServletRequest; 

public class MyFilter implements Filter { 
private FilterConfig filterConfig; 

public void init(FilterConfig filterConfig) throws ServletException { 
System.out.println("Filter initialized"); 
this.filterConfig = filterConfig; 


public void destroy() { 
System.out.println("Filter destroyed"); 
this.filterConfig = null; 


public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException { 
chain.doFilter(new MyRequestWrapper((HttpServletRequest) request), 
response); 


這個(gè)程序使用了列表6所示的filter來(lái)修整用戶輸入。要使用這個(gè)filter,你需要在web.xml文件中如下設(shè)置filter及filter-mapping的元素。 
   
<filter> 
       <filter-name>TrimmerFilter</filter-name> 
       <filter-class>trimmer.filter.MyFilter</filter-class> 
   </filter> 
   <filter-mapping> 
       <filter-name>TrimmerFilter</filter-name> 
       <url-pattern>*.do</url-pattern> 
   </filter-mapping> 


要測(cè)試這個(gè)filter,啟動(dòng)這個(gè)應(yīng)用后,在表單中輸入一些值,提交表單,看看這個(gè)filter是如何修整輸入數(shù)值的。這是一個(gè)實(shí)用的裝飾模式的應(yīng)用。 

小結(jié) 
Servlet  filter可以在調(diào)用一個(gè)servlet的服務(wù)方法后,攔載或加工HTTP請(qǐng)求。盡管這非常誘人,但其實(shí)際使用卻有所限制,因?yàn)槟悴荒芨淖僅ttpServletRequest對(duì)象。 
這時(shí)候裝飾模式派上了用場(chǎng)。本文演示了如何通過(guò)應(yīng)用裝飾模式來(lái)“修改”HttpServletRequest對(duì)象,從而使你的servlet  filter更加有用。在上面filter例子中,filter改了request參數(shù)中的用戶輸入,而這一點(diǎn),如果沒(méi)有裝飾request對(duì)象,你是無(wú)論如何也不可能做到的。 




--------------------------------------------------------- 
package wrapper;   
  
import java.io.UnsupportedEncodingException;   
import java.net.URLDecoder;   
  
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletRequestWrapper;   
  
public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {   
  
    private String charset = "UTF-8";   
  
    public GetHttpServletRequestWrapper(HttpServletRequest request) {   
        super(request);   
    }   
  
    /**  
     * 獲得被裝飾對(duì)象的引用和采用的字符編碼  
     * @param request  
     * @param charset  
     */  
    public GetHttpServletRequestWrapper(HttpServletRequest request,   
            String charset) {   
        super(request);   
        this.charset = charset;   
    }   
  
    /**  
     * 實(shí)際上就是調(diào)用被包裝的請(qǐng)求對(duì)象的getParameter方法獲得參數(shù),然后再進(jìn)行編碼轉(zhuǎn)換  
     */  
    public String getParameter(String name) {   
        String value = super.getParameter(name);   
        value = value == null ? null : convert(value);   
        return value;   
    }   
  
    public String convert(String target) {   
        System.out.println("編碼轉(zhuǎn)換之前:" + target);   
        try {   
            return new String(target.trim().getBytes("ISO-8859-1"), charset);   
        } catch (UnsupportedEncodingException e) {   
            return target;   
        }   
    }   
  

------------ 
public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain chain) throws IOException, ServletException {   
        //設(shè)置請(qǐng)求響應(yīng)字符編碼   
        request.setCharacterEncoding(charset);   
        response.setCharacterEncoding(charset);   
        //新增加的代碼           
        HttpServletRequest req = (HttpServletRequest)request;   
           
        if(req.getMethod().equalsIgnoreCase("get"))   
        {   
            req = new GetHttpServletRequestWrapper(req,charset);   
        }   
           
        System.out.println("----請(qǐng)求被"+config.getFilterName()+"過(guò)濾");   
        //傳遞給目標(biāo)servlet或jsp的實(shí)際上時(shí)包裝器對(duì)象的引用,而不是原始的HttpServletRequest對(duì)象   
        chain.doFilter(req, response);   
           
        System.out.println("----響應(yīng)被"+config.getFilterName()+"過(guò)濾");   
  
    } 
本文版權(quán)歸黑馬程序員web前端開發(fā)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處,謝謝!
作者:黑馬程序員web前端培訓(xùn)學(xué)院;
首發(fā):http://web.itheima.com/ 
8種
分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!