中文乱码解决办法

本文深入探讨了HTTP请求中中文参数出现乱码的原因,详细分析了Servlet3.0规范中关于请求参数编码的规定,提供了多种解决方案,包括配置web.xml中的编码Filter、设置Content-Type以及手动编解码的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、实际项目遇到的问题

客户端发送POST请求访问接口, 请求参数放在Body当中。每个参数utf-8编码,从获取出来的中文参数时乱码 请求截图:

服务器端获取company参数:request.getParameter("company") 为 ”æå»é¥¿æå»“。乱码!!

2.1、中文乱码的根本原因:

Servlet3.0规范中有关请求参数编码的解释如下: 当前很多浏览器并不发送带Content-Type头部的字符编码标识符,它会把字符编码的决定留在读取HTTP请求的时候。如果客户端没有指明编码,容器用来创建请求读和解析POST数据的默认编码必须是"ISO-8859-1"。然而,为了提示开发者客户端没有成功发送一个字符编码,容器中getCharacterEncoding方法会返回null。 如果客户端没有设置字符编码,并且请求数据使用了不同编码而不是上述的默认编码,程序将会出现中断。为了纠正这种状态,一个新的方法setCharacterEncoding(String enc) 被添加到ServletRequest接口。开发者调用这个方法能重写容器提供的字符编码。这个方法必须在解析request中任何post数据或者读任何输入之前调用。一旦数据已经被读取,调用这个方法不会影响它的编码。

2.2、另外一种理解:

setCharacterEncoding("utf-8"); 该函数是用来设置HTTP请求或者相应的编码格式 对于HttpServletRequest,是指提交参数的编码,指定后可以通过getParameter()方法直接获取到正确的字符串。如果不指定则默认使用is08859-1编码。参见下述“表单输入“。需要注意的是在执行setCharacterEncoding()之前 ,不能执行任何getParameter()获取参数。java doc上写明:This method must be called prior to reading request parameters or reading input using getReader()。而且该指定只对POST方法有效。对GET方法无效。分析原因:应该是在执行第一个getParameter()的时候。JAVA将会按照编码分析所有的提交参数,而后续的getParameter()将不再分析编码。所以setCharacterEncoding()无效。而对于GET方法请求时。请求的参数在URL上,一开始就已经按照编码分析所有的参数,setCharacterEncoding()自然就无效。 对于response, 则制定输出内容的编码, 同时改设置会传递给浏览器, 通知浏览器输出的内容所采用的编码。

3.1、解决方法:web.xml中配置编码Filter
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</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>
复制代码
注意:

1、web.xml中,这段配置要放在所有filter的最前面,否则会不生效,根本原因请见上述第三点的解释 2、两个初始化参数的作用,其实看这个Filter的源码就一目了然,这两个参数是用来决定是否要设置request和response中的编码。源码很简洁:

public class CharacterEncodingFilter extends OncePerRequestFilter {    
     private String encoding;    
     private boolean forceEncoding = false;    
     public CharacterEncodingFilter() { }    
     public void setEncoding(String encoding) {        
         this.encoding = encoding;    
     }    
     public void setForceEncoding(boolean forceEncoding) {        
         this.forceEncoding = forceEncoding;    
     }    
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {        
         if(this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {            
             request.setCharacterEncoding(this.encoding);            
             if(this.forceEncoding) {                
                 response.setCharacterEncoding(this.encoding);            
             }        
          }        
          filterChain.doFilter(request, response);    
     }
 }
复制代码
3.2、解决方法:设置Content-Type

如果post请求方式是x-www-form-urlencoded,那么设置如下: Content-Type=application/x-www-form-urlencoded;charset=utf-8 这样通过request对象取body体里面的中文是正常的。 这种方式有一点需要注意: 如果请求方式是multipart/form-data,如上设置会导致request取不到参数。Content-Type要与传递数据匹配(本文data)

3.3、手动编解码

例如参数为company

String company= new String(request.getParameter("company").getBytes("iso-8859-1"), "utf-8");
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值