Servlet & JSP - Decorating Requests and Responses

Servlet API 提供了四个包装类:ServletRequestWrapper、ServletResponseWrapper、HttpServletRequestWrapper、HttpServletReponseWrapper。这些包装类使用的频率很小,但却很有用。当 servlet 接收到请求,service 方法被调用时,我们可以使用这些包装类来包装 servlet 容器传递过来的 request 和 response 对象以改变 request 和 response 的行为。例如,当 HTTP 请求的参数包含中文字符时,不想在每个 servlet 里面都对其转换编码,可以使用过滤器去拦截请求,然后使用 HttpServletRequestWrapper 去装饰该请求,覆盖 getParameter、getParameterValues 等方法,使这些方法返回的参数是转换过编码的。

 

应用示例

自定义的 HttpServletRequestWrapper:

package com.huey.hello.wrapper;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

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

public class CharsetServletRequestWrapper extends HttpServletRequestWrapper {

    private HttpServletRequest request;
    private String oldCharset;
    private String newCharset;
    
    public CharsetServletRequestWrapper(HttpServletRequest request, String oldCharset, String newCharset) {
        super(request);
        this.request = request;
        this.oldCharset = oldCharset;
        this.newCharset = newCharset;
    }
    
    @Override
    public String getParameter(String name) {
        return convertCharset(request.getParameter(name));
    }
    
    @Override
    public String[] getParameterValues(String name) {
        return convertCharset(request.getParameterValues(name));
    }
    
    @Override
    public Map<String, String[]> getParameterMap() {
        final Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String[]> newMap = new Map<String, String[]>() {
            @Override
            public int size() {
                return parameterMap.size();
            }

            @Override
            public boolean isEmpty() {
                return parameterMap.isEmpty();
            }

            @Override
            public boolean containsKey(Object key) {
                return parameterMap.containsKey(key);
            }

            @Override
            public boolean containsValue(Object value) {
                return parameterMap.containsValue(value);
            }

            @Override
            public String[] get(Object key) {
                return convertCharset(parameterMap.get(key));
            }

            @Override
            public String[] put(String key, String[] value) {
                return parameterMap.put(key, value);
            }

            @Override
            public String[] remove(Object key) {
                return parameterMap.remove(key);
            }

            @Override
            public void putAll(Map<? extends String, ? extends String[]> m) {
                parameterMap.putAll(m);
            }

            @Override
            public void clear() {
                parameterMap.clear();
            }

            @Override
            public Set<String> keySet() {
                return parameterMap.keySet();
            }

            @Override
            public Collection<String[]> values() {
                return convertCharset(parameterMap.values());
            }

            @Override
            public Set<Map.Entry<String, String[]>> entrySet() {
                return convertCharset(parameterMap.entrySet());
            }
        };
        
        return newMap;
    }
    
    private String convertCharset(String str) {
        String newStr;
        try {
            newStr = new String(str.getBytes(oldCharset), newCharset);
        } catch (UnsupportedEncodingException e) {
            newStr = str;
        }
        return newStr;
    }
    
    private String[] convertCharset(String[] strs) {
        String[] newStrs = null;
        if (strs != null) {
            newStrs = new String[strs.length];
            for (int i = 0; i < newStrs.length; i++) {
                newStrs[i] = convertCharset(strs[i]);
            }
        }
        return newStrs;
    }
    
    private Collection<String[]> convertCharset(Collection<String[]> valueCollection) {
        Collection<String[]> newCollection = new ArrayList<String[]>();
        for (String[] values : valueCollection) {
            newCollection.add(convertCharset(values));
        }
        return newCollection;
    }
    
    private Set<Entry<String, String[]>> convertCharset(Set<Map.Entry<String, String[]>> entrySet) {
        Set<Map.Entry<String, String[]>> newSet = new HashSet<Map.Entry<String, String[]>>();
        for (final Map.Entry<String, String[]> entry : entrySet) {
            Map.Entry<String, String[]> newEntry = new Map.Entry<String, String[]> () {
                @Override
                public String getKey() {
                    return entry.getKey();
                }
                @Override
                public String[] getValue() {
                    return convertCharset(entry.getValue());
                }
                @Override
                public String[] setValue(String[] value) {
                    return entry.setValue(value);
                }
            };
            newSet.add(newEntry);
        }
        return newSet;
    }
    
}

过滤器:

package com.huey.hello.filters;

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.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;

import com.huey.hello.wrapper.CharsetServletRequestWrapper;

@WebFilter(filterName="charsetFilter", urlPatterns = {"/*"}, 
        initParams = {
                @WebInitParam(name = "oldCharset", value = "ISO-8859-1"),
                @WebInitParam(name = "newCharset", value = "UTF-8"),
        })
public class CharsetFilter implements Filter {

    private String oldCharset;
    private String newCharset;
            
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        oldCharset = filterConfig.getInitParameter("oldCharset");
        newCharset = filterConfig.getInitParameter("newCharset");
    }
    
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding(newCharset);
        response.setContentType("text/plain;charset=" + newCharset);
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        CharsetServletRequestWrapper requestWrapper = new CharsetServletRequestWrapper(httpRequest, oldCharset, newCharset);         
        chain.doFilter(requestWrapper, response);
    }

}

 

posted on 2016-05-11 19:55  huey2672  阅读(277)  评论(0编辑  收藏  举报