详解get请求和post请求参数中文乱码的解决办法

2 篇文章 0 订阅
1 篇文章 0 订阅

参考链接:
1、详解get请求和post请求参数中文乱码的解决办法
https://www.cnblogs.com/cdf-opensource-007/p/6337448.html
2、解决Spring MVC中get请求参数乱码的一种不改tomcat配置解决方法
http://blog.csdn.net/quiet_coding/article/details/60573186
3、使用过滤器(Filter)解决请求参数中文乱码问题(复杂方式)
https://www.cnblogs.com/CQY1183344265/p/5863371.html
post请求:客户端字节流(utf-8)–tomcat使用请求头中的编码(contentType),读取字节流,如果没有指定则使用tomcat的默认编码(ISO-8859-1);
get请求:客户端请求url–tomcat使用tomcat的编码(ISO-8859-1)解析url地址,获取get参数;

首先出现中文乱码的原因是tomcat默认的编码方式是”ISO-8859-1”,这种编码方式以单个字节作为一个字符,而汉字是以两个字节表示一个字符的。

一、get请求参数中文乱码的解决办法

对于get请求解决中文乱码有两种途径
1、修改tomcat默认的编码方式为”UTF-8”

在tomcat的server.xml里把

<Connector connectionTimeout="50000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

修改为

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

使用这种方式带来的问题是在你本机上这么做没有问题,你无论怎么去修改你tomcat上的配置都没问题,但是测试环境和生产环境的服务器不是轻易说改就能改的,特别是有些公司的服务器是租赁的,那么在我们不知道测试环境和生产环境服务器配置的时候就要使用以下的方法来解决get请求的中文乱码问题。


2、手动编码解决乱码

这句话的确管用,可以解决乱码问题,但只要是get请求,就需要对每个参数进行手动解码,太繁琐。所以就对spring的编码过滤器下手吧,对其进行改造,让他支持get请求解码。

// 获取前台传递过来的查询条件,中文乱码
String conditions = request.getParameter("extra_search");
//用 ISO8859-1 编码,用utf-8解码
conditions = new String(conditions.getBytes("ISO8859-1"), "UTF-8").trim();

3、通过过滤器解决get请求乱码(post乱码同样处理了)

编码过滤器如下:
也可以参考这个链接:解决Spring MVC中get请求参数乱码的一种不改tomcat配置解决方法http://blog.csdn.net/quiet_coding/article/details/60573186

package edu.hrbeu.platform.modeling.common.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 
* @ClassName: EncodingFilter 
* @Description: TODO(自定义编码过滤器,解决post和get乱码问题)
* 说明:tomcat的配置编码为iso8859-1(默认为iso8859-1),get乱码能够解决,否则无法解决get乱码
* @author chenliming
* @date 2018年2月5日 下午4:24:36 
*
 */
public class EncodingFilter extends OncePerRequestFilter {
    private String encoding;

    private boolean forceEncoding = false;

    /**
     * Set the encoding to use for requests. This encoding will be passed into a
     * {@link javax.servlet.http.HttpServletRequest#setCharacterEncoding} call.
     * <p>
     * Whether this encoding will override existing request encodings (and
     * whether it will be applied as default response encoding as well) depends
     * on the {@link #setForceEncoding "forceEncoding"} flag.
     */
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * Set whether the configured {@link #setEncoding encoding} of this filter
     * is supposed to override existing request and response encodings.
     * <p>
     * Default is "false", i.e. do not modify the encoding if
     * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()}
     * returns a non-null value. Switch this to "true" to enforce the specified
     * encoding in any case, applying it as default response encoding as well.
     * <p>
     * Note that the response encoding will only be set on Servlet 2.4+
     * containers, since Servlet 2.3 did not provide a facility for setting a
     * default response encoding.
     */
    public void setForceEncoding(boolean forceEncoding) {
        this.forceEncoding = forceEncoding;
    }

    public String filter(HttpServletRequest request, String input) {
        String ret = input;
        // 客户端请求参数值可能为(null)服务端过滤掉当null处理即可
        if (input == null || input.trim().equals("(null)")) {
            ret = null;
            return ret;
        }
        final String method = request.getMethod();
        // 该处可以实现各种业务的自定义的过滤机制
        if (method.equalsIgnoreCase("get")) {
            try {
                ret = new String(input.getBytes("ISO8859-1"), this.encoding);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    @Override
    protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response,
            FilterChain filterChain) throws ServletException, IOException {
        // 设置request和response的编码格式(解决post请求乱码)
        if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
            request.setCharacterEncoding(this.encoding);
            if (this.forceEncoding) {
                response.setCharacterEncoding(this.encoding);
            }
        }
        // 对request中的参数进行编码格式的转换(解决get请求乱码)
        filterChain.doFilter(new HttpServletRequestWrapper(request) {
            @Override
            public String getParameter(String name) {
                String value = super.getParameter(name);
                return filter(this, value);
            }

            @Override
            public String[] getParameterValues(String name) {
                String[] values = super.getParameterValues(name);
                if (values == null) {
                    return null;
                }
                for (int i = 0; i < values.length; i++) {
                    values[i] = filter(this, values[i]);
                }
                return values;
            }
        }, response);
    }
}

web.xml配置文件:配置编码过滤器

<!--  自定义过滤器进行编码格式的设置-start-牛迁迁-2016年3月18日15:25:45 -->
<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>edu.hrbeu.platform.modeling.common.filter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 编码格式的设置 end 牛迁迁 -->

总结:
(1)上面过滤器的核心就是doFilterInternal方法,在这个方法中设置了request和response的编码格式,并且新增了对request中参数进行编码格式转换的方法。

(2) 其中OncePerRequestFilter这个抽象过滤器很好的实现了对每个request只执行一次过滤操作,如果有类似的需求可以继承该类并实现doFilterInternal方法来完成。

(3)forceEncoding=true是意思是指无论客户端请求是否包含了编码,都用过滤器里的编码来解析请求

这样编码问题就得以完美解决了,不过要注意的是编码问题一定要尽早发现和解决,要不然后期发现改动起来代价会很大。


二、post请求参数中文乱码的解决办法

1、request.setCharacterEncoding("UTF-8");
2、spring的自带的编码过滤器,能够解决post请求乱码,但是无法解决get请求乱码:

web.xml文件配置编码过滤器:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <async-supported>true</async-supported>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值