<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>


    草之戒_
    posts - 2,comments - 14,trackbacks - 0
          當(dāng)我們在做web應(yīng)用的時候都會處理客戶端提交到服務(wù)器的數(shù)據(jù),如去除前后空格,一些非常字符,SQL注入類似的東西,在這里我主要說前后空格我是怎么來解決的,其它也都可以照此方法快速、方便、有效的解決,但是我一般對于非法字符,都是采用了標(biāo)簽來解決它的,并沒有使用Filter轉(zhuǎn)義掉(純屬個人解決辦法)。
          去除前后空格看似非常簡單的事,但是有許多人可能就是因?yàn)檫@一個小問題,折磨自己半天,客戶端提交到所有的東西,都是以字符串形式提交的,我們不知道客戶是怎么操作的,他可能把一個age屬性對應(yīng)的值,在輸入時多加了一個空格,而服務(wù)器age對應(yīng)的卻是Integer類型,如果你使用servlet這事也好解決,但是如果你使用的是MVC框架,自動封裝時就會得到一個類型轉(zhuǎn)換異常,然而這個時候你是否有好的解決辦法呢?
          這里我使用Filter來解決這一問題,這是最簡單方便有效的解決方式,因?yàn)槟悴恍枰獙γ恳粋€屬性在封裝前都去trim(),因?yàn)檫@是一件非常乏味的事情。大家都知道filter可以過濾我們想要它過濾的每一個請求,在這請求中有HttpServletRequest、HttpServletResponse。我們知道服務(wù)器取得客戶端發(fā)送的參數(shù)都是通過HttpServletRequest來獲取的,那我們可不可以在使用HttpServletRequest取值的時候就為每一個客戶端提交的屬性去除前后空格,或者其它的一些過濾操作。這肯定是可以的,那我們先來了解一下服務(wù)器是怎么取得客戶端的值的。
    1.getParameter(name),返回單個值。
    2.getParameterValues(name),返回一個數(shù)組。
    3.getParameterMap(),把客戶端提交參數(shù)封裝為一個Map返回。K:name,V:value。
          當(dāng)我們使用servlet的時候一般都是使用前兩種,struts1使用的第2種,struts2(xwork)則使用的第3種,那么我們只要在這三個方法調(diào)用的時候處理前后空格,那么返回到服務(wù)器的參數(shù)就又減少了一分出bug的機(jī)會,看下面的實(shí)現(xiàn)。
    public class RequestParameterFilter implements Filter {

        
    private static Log log = LogFactory.getLog(RequestParameterFilter.class);

        
    private List<String> excludeNames;

        
    public void destroy() {

        }

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

        
    public void init(FilterConfig config) throws ServletException {
            String exclude 
    = config.getInitParameter("exclude");
            
    // not is null.
            if (exclude != null && exclude.length() > 0) {
                excludeNames 
    = Arrays.asList(exclude.split(","));
                
    if (log.isDebugEnabled()) {
                    log.debug(
    "initialize arguments.");
                }
            }
        }

        
    /**
         * 該類繼承之HttpServletRequestWrapper,并重寫了對應(yīng)取得客戶端相當(dāng)參數(shù)值的所有的方法。
         * <ul>
         * <li>getParameter</li>
         * <li>getParameterValues</li>
         * <li>getParameterMap</li>
         * </ul>
         * 
         * 
    @version 1.0/2010-6-10 上午11:25:47
         * 
    @author Aidan
         * 
    @see HttpServletRequestWrapper
         
    */
        
    private class HttpServletRequestWrapper2 extends HttpServletRequestWrapper {

            
    private ParameterMap2 pm2;

            
    public HttpServletRequestWrapper2(HttpServletRequest request) {
                
    super(request);
            }

            
    public String getParameter(String name) {
                
    if (excludeNames != null && excludeNames.contains(name)) {
                    
    return super.getParameter(name);
                }
                
    return trim(super.getParameter(name));
            }

            @SuppressWarnings(
    "unchecked")
            
    public Map getParameterMap() {
                
    // xwork便使用此方法取值
                
    // 該方法返回一個Map,Map映射了客戶端請求對應(yīng)的鍵值(K,V)。
                if (pm2 == null) {
                    pm2 
    = new ParameterMap2(super.getParameterMap());
                }
                
    return pm2;
            }

            
    public String[] getParameterValues(String name) {
                
    // Struts1使用此方法取得所有的參數(shù)值
                if (excludeNames != null && excludeNames.contains(name)) {
                    
    return super.getParameterValues(name);
                }
                
    return (String[]) trim(super.getParameterValues(name));
            }
        }

        
    /**
         * 該此繼承自HashMap。
         * 
         * 
    @version 1.0/2010-6-10 上午11:30:13
         * 
    @author Aidan
         * 
    @see HashMap
         
    */
        @SuppressWarnings( { 
    "unchecked""serial" })
        
    private class ParameterMap2 extends HashMap {

            
    private Set entrySet;

            
    /**
             * 若要構(gòu)造此類對象,則需要傳入一個map參數(shù),該map對應(yīng)的客戶端請求的參數(shù)(K,V)。
             * 
             * 
    @param map
             *            映射客戶端參數(shù)。
             
    */
            
    public ParameterMap2(Map map) {
                
    super(map);
            }

            
    public Set entrySet() {
                
    // xwork使用了此方法取值
                if (entrySet == null) {
                    entrySet 
    = new HashSet();
                    Set temSet 
    = super.entrySet();
                    
    for (Iterator iterator = temSet.iterator(); iterator.hasNext();) {
                        Map.Entry me 
    = (Map.Entry) iterator.next();
                        Entry2 entry 
    = new Entry2(me);
                        entrySet.add(entry);
                    }
                }
                
    return entrySet;
            }

            
    // 若直接從map使用key取得
            public Object get(Object key) {
                Object value 
    = super.get(key);
                
    // 不過濾此對象
                if (excludeNames != null && excludeNames.contains(key)) {
                    
    return value;
                }
                
    if (value != null) {
                    
    return trim(value);
                }
                
    return null;
            }
        }

        @SuppressWarnings(
    "unchecked")
        
    private class Entry2<K, V> implements Map.Entry<K, V> {
            
    private Map.Entry me;
            
    private boolean isTrim = true;

            
    public Entry2(Map.Entry me) {
                
    if (me == null) {
                    
    throw new IllegalArgumentException(
                            
    "Map.Entiry argument not null.");
                }
                
    this.me = me;
                
    // 不過濾此對象
                if (excludeNames != null && excludeNames.contains(me.getKey())) {
                    isTrim 
    = false;
                }
            }

            
    public K getKey() {
                
    return (K) me.getKey();
            }

            
    public V getValue() {
                
    if (isTrim) {
                    
    return (V) trim(me.getValue());
                }
                
    return (V) me.getValue();
            }

            
    public V setValue(V value) {
                
    return (V) me.setValue(value);
            }

        }

        
    /**
         * 去除一個Object類型對應(yīng)的前后空格,因?yàn)榭蛻舳颂峤粎?shù)有兩種,一種:String,另一種:String[],此方法會自動判斷調(diào)用哪個方法。
         * 
         * 
    @param value
         *            需要處理的參數(shù)。
         * 
    @return 處理后的值。
         
    */
        
    protected Object trim(Object value) {
            
    if (value instanceof String[]) {
                
    return trim((String[]) value);
            }
            
    return trim(value.toString());
        }

        
    /**
         * 去除某個字符串的前后空格。
         * 
         * 
    @param value
         *            需要處理的參數(shù)。
         * 
    @return 處理后的值。
         
    */
        
    protected String trim(String value) {
            
    if (value != null && value.length() > 0) {
                
    return value.trim();
            }
            
    return value;
        }

        
    /**
         * 去除某個數(shù)組中所有的值的前后空格。
         * 
         * 
    @param values
         *            需要處理的數(shù)組。
         * 
    @return 處理后的值,當(dāng)數(shù)組的length為1時,則返回一個String,反之返回一個數(shù)組。
         
    */
        
    protected Object trim(String[] values) {
            
    if (values != null && values.length > 0) {
                
    int len = values.length;
                
    for (int i = 0; i < len; i++) {
                    values[i] 
    = trim(values[i]);
                }
            }
            
    if (values.length == 1) {
                
    return values[0];
            }
            
    return values;
        }

        
    /**
         * 
         * 
    @return 不處理的對象。
         
    */
        
    public List<String> getExcludeNames() {
            
    return excludeNames;
        }

    }
          這個Filter實(shí)現(xiàn)原理非常簡單,我會過濾所有的請求,HttpServletRequestWrapper2繼承自HttpServletRequestWrapper,在構(gòu)造函數(shù)中需要一個HttpServletRequest對象(這個request是web窗口創(chuàng)建的),然后我重載了上面所說的3個方法,在方法內(nèi)部每次會去過濾當(dāng)前值,這是利用了Java多態(tài)特性。在使用getParameterMap時較為麻煩,原理一樣。
          當(dāng)然我們有時候可能有些特殊情況不需要過濾前后空格或者其它一些規(guī)則,這里我們可以使用exclude屬性來判斷是否過濾此屬性。
    DEMO:
    <form action="test!create.action" method="post">
                name:
                
    <input name="name" value=" My name is haha.. " />
                
    <br />
                
    <!-- This is a String,isn't number. -->
                age:
                
    <input name="age" value="   15  " />
                
    <br />
                email:
                
    <input name="email" value=" grasszring@gmail.com " />
                
    <br />
                email2:
                
    <input name="email" value=" grasszring@foxmail.com " />
                
    <br />
                
    <input type="submit" value=" submit " />
    </form>
    web.xml
    <filter>
            
    <filter-name>requestParameter</filter-name>
            
    <filter-class>com.onlyeffort.commons.web.filter.RequestParameterFilter</filter-class>
            
    <init-param>
                
    <!-- 不需要過濾此參數(shù) -->
                
    <param-name>exclude</param-name>
                
    <param-value>email</param-value>
            
    </init-param>
        
    </filter>
        
    <filter-mapping>
            
    <filter-name>requestParameter</filter-name>
            
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    action
    @Action(params = { "actionName""test" })
    @Result(location 
    = "http://www.google.com", type = "redirect")
    @SuppressWarnings(
    "serial")
    public class TestController extends ActionSupport {

        
    private String name;
        
    private Integer age;
        
    private String[] email;
            
    //.. get set method.

        @Override
        
    public String create() throws CreateFailureException {
            System.out.println(name);
            System.out.println(age);
            
    for (String mail : email) {
                System.out.println(mail);
            }        
            
    return SUCCESS;
        }
    }

          OK,如果大家有什么問題或有什么意見都盡管留言,感激不盡。


    轉(zhuǎn)載時請注明轉(zhuǎn)載地址,onlyeffort.QQ:501276913
    posted on 2010-06-10 14:45 Aidan 閱讀(2224) 評論(7)  編輯  收藏

    FeedBack:
    # re: 快速、方便、有效的Filter
    2010-06-11 09:29 | regale
    不錯!學(xué)習(xí)了  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-06-13 00:30 | zcl
    一個簡單的功能有必要搞得這么復(fù)雜嗎?雖然你這個filter可以去掉空格,也可以通過配置選擇不去掉哪些字段的空格,但你在action中還是要判斷傳過來的屬性是否為空,也就是說也要判斷形如:if (name != null)...,其實(shí)搞開發(fā)的已經(jīng)習(xí)慣了這種風(fēng)格的代碼:if (name != null &&!name.trim().equals(""))的形式了,這種寫法已經(jīng)很通用了,可讀性很好!  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-06-13 08:36 | Aidan
    @zcl
    可能你沒有仔細(xì)查看我的例子,你仔細(xì)看age是一個Integer類型,但是client傳的卻是一個不能轉(zhuǎn)換為Integer的String字符串,這時候你使用MVC框架該如何?我在里面也清楚的說明了。  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-07-15 17:28 | jj
    如果只是去空格的話,filter大材小用了。與靈活性相比,我寧愿寫一個util來封裝requst取到的param。搞的這么復(fù)雜的確沒有必要  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-07-15 22:39 | Aidan
    @jj
    那我請問你,假如我們使用mvc框架的時候,你的util類如何使用??  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-07-16 00:07 | jj
    @Aidan
    與使用mvc框架什么關(guān)系?就不能用util類了?java.util的工具類你在mvc框架下從來不用?  回復(fù)  更多評論
      
    # re: 快速、方便、有效的Filter
    2010-07-16 00:35 | jj
    @Aidan
    還有,這么簡單的一個應(yīng)用又何必小題大做爭論來爭論去呢?你的實(shí)現(xiàn)沒有問題,只不過是看有沒有必要,還有很多更簡潔更方便,至少exclude的時候不用重啟容器的方法。不同情況,不同考慮。總之,這原本就是一個最最基本的問題,又有n多最最基本的解決方法,每種方法各有利弊,多說無益,相信有很多人瀏覽過卻沒有留言就是這個原因  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    編程部落   qq群:37996359(上限500人,一起關(guān)注java、討論技術(shù),互相學(xué)習(xí),共同進(jìn)步)
    主站蜘蛛池模板: 亚洲Aⅴ无码专区在线观看q| 青柠影视在线观看免费高清| 亚洲AV无码国产丝袜在线观看| 国产亚洲精品免费| 免费下载成人电影| 13小箩利洗澡无码视频网站免费| 久久精品熟女亚洲av麻豆| 亚洲国产午夜精品理论片 | 精品日韩亚洲AV无码一区二区三区| 国产在线19禁免费观看| 一二三四在线观看免费高清中文在线观看| 大妹子影视剧在线观看全集免费| 国产精品亚洲二区在线| 亚洲人成网亚洲欧洲无码| 亚洲国产精品白丝在线观看| 亚洲国产人成在线观看69网站| 日韩精品亚洲aⅴ在线影院| 亚洲精品第一国产综合境外资源| 国产无遮挡裸体免费视频| 在线观看免费高清视频| 色窝窝免费一区二区三区| 99久久国产热无码精品免费| 无码一区二区三区免费| 日韩免费在线观看视频| 中文成人久久久久影院免费观看 | 在线观看特色大片免费视频| 一级毛片**不卡免费播| 久草视频在线免费看| 欧洲人免费视频网站在线| 国产日韩AV免费无码一区二区| 国产黄色片免费看| 丝袜捆绑调教视频免费区| 高清永久免费观看| 久久久久久免费一区二区三区| 免费人成黄页在线观看日本| 久久99精品免费视频| 亚洲一级毛片免费观看| 免费不卡视频一卡二卡| 成人黄动漫画免费网站视频| 四虎成人精品一区二区免费网站 | 在线播放亚洲精品|