http get 中文乱码解决方案

基于spring MVC体系下,本身提供了CharacterEncodingFilter支持,使得大部分情况可以通过此filter来完成字符集转码,但在一种情况下,即在http get方式提交的中文参数无法完成正确的转码,原因是request.setCharacterEncoding(charset)只能完成消息体的内容有作用,而对地址参数中的中文无法完成。

有两种方式可以完成

一、在tomcat的server.xml中配置connector上配置URIEncoding

<Connector port="8080" protocol="HTTP/1.1"   
           connectionTimeout="20000"   
           redirectPort="8443"   
           URIEncoding="UTF-8"  
 />

   注:此方式对外部容器有潜入要求,不太建议使用

二、写一个filter,完成对request中getParameter的包装

public class RequestParameterFilter extends OncePerRequestFilter {
    private static final Logger logger          = LoggerFactory
                                                    .getLogger(RequestParameterFilter.class);

    /** 默认字符集 */
    private static final String DEFAULT_CHARSET = "UTF-8";

    /*
     * (non-Javadoc)
     * @see org.springframework.web.filter.OncePerRequestFilter#doFilterInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain)
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        // 重新包装请求
        request = new HttpServletRequestWrapper4Query((HttpServletRequest) request);

        filterChain.doFilter(request, response);
    }

    private class HttpServletRequestWrapper4Decode extends HttpServletRequestWrapper {
        private ParameterMapWrapper paramMap;

        /** 构造 */
        public HttpServletRequestWrapper4Decode(HttpServletRequest request) {
            super(request);
        }

        /*
         * (non-Javadoc)
         * @see javax.servlet.ServletRequestWrapper#getParameter(java.lang.String)
         */
        @Override
        public String getParameter(String name) {
            return decode(super.getParameter(name));
        }

        public String[] getParameterValues(String name) {
            return decode(super.getParameterValues(name));
        }

        /*
         * (non-Javadoc)
         * @see javax.servlet.ServletRequestWrapper#getParameterMap()
         */
        @Override
        public Map getParameterMap() {
            if (paramMap == null) {
                paramMap = new ParameterMapWrapper(super.getParameterMap());
            }

            return paramMap;
        }
    }

    /**
     * 该此继承自HashMap。
     * @see HashMap
     */
    @SuppressWarnings({ "serial" })
    private class ParameterMapWrapper extends HashMap {
        private Set entrySet;

        /** 构造 */
        public ParameterMapWrapper(Map map) {
            super(map);
        }

        /*
         * (non-Javadoc)
         * @see java.util.HashMap#entrySet()
         */
        @Override
        public Set entrySet() {
            if (entrySet == null) {
                entrySet = new HashSet();
                Set temSet = super.entrySet();
                for (Iterator iterator = temSet.iterator(); iterator.hasNext();) {
                    Map.Entry me = (Map.Entry) iterator.next();
                    EntryWarper entry = new EntryWarper(me);
                    entrySet.add(entry);
                }
            }
            return entrySet;
        }

        /*
         * (non-Javadoc)
         * @see java.util.HashMap#get(java.lang.Object)
         */
        @Override
        public Object get(Object key) {
            Object value = super.get(key);
            if (value != null) {
                return decode(value);
            }
            return null;
        }
    }

    /**
     * entry包装
     * @see Map.Entry
     */
    private class EntryWarper<K, V> implements Map.Entry<K, V> {
        private Map.Entry me;

        /** 构造 */
        public EntryWarper(Map.Entry me) {
            if (me == null) {
                throw new IllegalArgumentException("Map.Entiry argument not null.");
            }
            this.me = me;
        }

        /*
         * (non-Javadoc)
         * @see java.util.Map.Entry#getKey()
         */
        @Override
        public K getKey() {
            return (K) me.getKey();
        }

        /*
         * (non-Javadoc)
         * @see java.util.Map.Entry#getValue()
         */
        @Override
        public V getValue() {
            return (V) decode(me.getValue());
        }

        /*
         * (non-Javadoc)
         * @see java.util.Map.Entry#setValue(java.lang.Object)
         */
        @Override
        public V setValue(V value) {
            return (V) me.setValue(value);
        }
    }

    /**
     * decode处理
     * @param value 需要处理的参数。
     * @return 处理后的值。
     */
    protected Object decode(Object value) {
        if (value instanceof String[]) {
            return decode((String[]) value);
        }
        if (value instanceof String) {
            return decode((String) value);
        }
        return value;
    }

    /**
     * 字符串处理
     * @param value
     * @return
     */
    protected String decode(String value) {
        if (StringUtil.isNotBlank(value)) {
            try {
                return URLDecoder.decode(value, DEFAULT_CHARSET);
            } catch (UnsupportedEncodingException e) {
                logger.error("URLDecode异常", e);
                // 忽略
            }
        }
        return value;
    }

    /**
     * 数组处理
     * @param values
     * @return 
     */
    protected String[] decode(String[] values) {
        if (values != null && values.length > 0) {
            int len = values.length;
            for (int i = 0; i < len; i++) {
                values[i] = decode(values[i]);
            }
        }

        return values;
    }

}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值