`

URIEncoding与useBodyEncodingForURI 在tomcat中文乱码处理上的区别及CharacterEncodingFilter

 
阅读更多

大家知道tomcat5.0开始,对网页的中文字符的post或者get,经常会出现乱码现象。

 

具体是因为Tomcat默认是按ISO-8859-1进行URL解码,ISO-8859-1并未包括中文字符,这样的话中文字符肯定就不能被正确解析了。

 

常见的解决方法是在tomcat的server.xml下的connetor属性中增加URIEncoding或者useBodyEncodingForURI属性。

 

但是,这两种方式有什么区别呢?

 

我简单谈一下自己的理解:

 

按照tomcat-docs/config/http.html文档的说明

 

URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used. 

useBodyEncodingForURI:This specifies if the encoding specified in contentType should be used for URI query parameters, instead of using the URIEncoding.

 

 

 

也就是说,

 

 useBodyEncodingForURI参数表示是否用request.setCharacterEncoding 
参数对URL提交的数据和表单中GET方式提交的数据进行重新编码,在默认情况下,该参数为false。

 

URIEncoding参数指定对所有GET方式请求进行统一的重新编码(解码)的编码。

 

 

 

URIEncoding和useBodyEncodingForURI区别是,

 

URIEncoding是对所有GET方式的请求的数据进行统一的重新编码,

 

而useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码,不同的页面可以有不同的重新编码的编码

 

 

 

 

 

再详细点的======================================================================================================

 

本文章会从tomcat的源码角度来解析Tomcat的两个参数设置URIEncoding和useBodyEncodingForURI。 

对于一个请求,常用的有两种编码方式,如下:
 

 

Java代码  收藏代码
  1. <!DOCTYPE html>  
  2. <html>  
  3.     <head>  
  4.         <meta charset="utf-8" />  
  5.         <title></title>  
  6.     </head>  
  7.     <body>  
  8.         <form action="http://127.0.0.1:8080/string?name=中国" method="post">  
  9.             <input type="text" name="user" value="张三"/>  
  10.             <input type="submit" value="提交"/>  
  11.         </form>  
  12.     </body>  
  13. </html>  


首先说说结论: 
上述请求有两处含有中文,一处是请求参数中,即?name='中国',另一处是请求体中,即user='张三'。对于这两处tomcat7是分两种编码方式的。URIEncoding就是针对请求参数的编码设置的,而filter的request.setCharacterEncoding('UTF-8')或者请求header中的content-type中的编码都是针对请求体的。不要把他们搞混了。 

useBodyEncodingForURI=true是说,请求参数的编码方式要采用请求体的编码方式。当useBodyEncodingForURI=true时,若请求体采用utf-8解析,则请求参数也要采用utf-8来解析。这两个属性值的设置在tomcat的conf/server.xml文件中配置,如下:
 

Java代码  收藏代码
  1. <Service name="Catalina">  
  2.   
  3.    <!--The connectors can use a shared executor, you can define one or more named thread pools-->  
  4.    <!--  
  5.    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"  
  6.        maxThreads="150" minSpareThreads="4"/>  
  7.    -->  
  8.   
  9.   
  10.    <!-- A "Connector" represents an endpoint by which requests are received  
  11.         and responses are returned. Documentation at :  
  12.         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)  
  13.         Java AJP  Connector: /docs/config/ajp.html  
  14.         APR (HTTP/AJP) Connector: /docs/apr.html  
  15.         Define a non-SSL HTTP/1.1 Connector on port 8080  
  16.    -->  
  17.    <Connector port="8080" protocol="HTTP/1.1"  
  18.               connectionTimeout="20000"  
  19.               redirectPort="8443" useBodyEncodingForURI='true' URIEncoding='UTF-8' />  
  20.    <!-- A "Connector" using the shared thread pool-->  


这样写只是说明这两者的配置位置,并不是两个属性要同时配置,不要理解错了。 
继续说说CharacterEncodingFilter的作用。 
使用方式,将如下代码加入web.xml文件中:
 

Java代码  收藏代码
  1. <filter>  
  2.         <filter-name>encoding</filter-name>  
  3.         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
  4.         <init-param>  
  5.             <param-name>encoding</param-name>  
  6.             <param-value>UTF-8</param-value>  
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>forceEncoding</param-name>  
  10.             <param-value>true</param-value>  
  11.         </init-param>  
  12.     </filter>  
  13.   
  14.     <filter-mapping>  
  15.         <filter-name>encoding</filter-name>  
  16.         <url-pattern>/*</url-pattern>  
  17.     </filter-mapping>  


作用是,当forceEncoding为false的前提下(默认为false),当request没有指定content-type或content-type不含编码时,该filter将会为这个request设定请求体的编码为filter的encoding值。 
当forceEncoding为true的前提下,就会为request的请求体和response都设定为这个filter的encoding值。 
CharacterEncodingFilter源码如下:
 

Java代码  收藏代码
  1. public class CharacterEncodingFilter extends OncePerRequestFilter {  
  2.   
  3.     private String encoding;  
  4.   
  5.     private boolean forceEncoding = false;  
  6.   
  7.   
  8.     /** 
  9.      * Set the encoding to use for requests. This encoding will be passed into a 
  10.      * {@link javax.servlet.http.HttpServletRequest#setCharacterEncoding} call. 
  11.      * <p>Whether this encoding will override existing request encodings 
  12.      * (and whether it will be applied as default response encoding as well) 
  13.      * depends on the {@link #setForceEncoding "forceEncoding"} flag. 
  14.      */  
  15.     public void setEncoding(String encoding) {  
  16.         this.encoding = encoding;  
  17.     }  
  18.   
  19.     /** 
  20.      * Set whether the configured {@link #setEncoding encoding} of this filter 
  21.      * is supposed to override existing request and response encodings. 
  22.      * <p>Default is "false", i.e. do not modify the encoding if 
  23.      * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()} 
  24.      * returns a non-null value. Switch this to "true" to enforce the specified 
  25.      * encoding in any case, applying it as default response encoding as well. 
  26.      * <p>Note that the response encoding will only be set on Servlet 2.4+ 
  27.      * containers, since Servlet 2.3 did not provide a facility for setting 
  28.      * a default response encoding. 
  29.      */  
  30.     public void setForceEncoding(boolean forceEncoding) {  
  31.         this.forceEncoding = forceEncoding;  
  32.     }  
  33.   
  34.   
  35.     @Override  
  36.     protected void doFilterInternal(  
  37.             HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
  38.             throws ServletException, IOException {  
  39.   
  40.         if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {  
  41.             request.setCharacterEncoding(this.encoding);  
  42.             if (this.forceEncoding) {  
  43.                 response.setCharacterEncoding(this.encoding);  
  44.             }  
  45.         }  
  46.         filterChain.doFilter(request, response);  
  47.     }  
  48.   
  49. }  


这个filter有两个属性,encoding和forceEncoding,我们可以在web.xml文件中来设定这两个属性值。 
每次request请求到来执行方法doFilterInternal,首先调用request.getCharacterEncoding(),本质就是从请求header content-type中获取编码值,如果没有,则调用request.setCharacterEncoding(this.encoding)将该filter的encoding值设置为请求体的编码方式,记住该编码方式只对请求体,不针对请求参数。当forceEncoding=true时,不管请求header content-type有没有编码方式,始终将该filter的encoding值设置到request和response中,同样只针对request的请求体。 

分享到:
评论

相关推荐

    java解决中文乱码问题

    Tomcat 5.5 中文乱码的问题可以使用 CharacterEncodingFilter 来解决。首先,需要将 %TOMCAT 安装目录%/webapps/servlets-examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.class 文件拷到你的 webapp ...

    使用过滤器解决中文乱码问题

    在Web开发过程中,经常遇到的一个问题是中文或其它非ASCII字符的乱码问题。这种现象通常出现在浏览器接收的数据与实际编码格式不匹配时。解决此类问题的一种常见方法是使用过滤器(Filter)对请求进行预处理,以确保...

    struts中文乱码问题解决详细步骤

    然而,在处理中文字符时,可能会遇到乱码问题,这主要体现在请求参数、响应内容或者静态资源显示上。解决这个问题通常涉及到编码设置的调整,下面将详细介绍两种方法来解决Struts中的中文乱码问题。 **方法一:配置...

    struts 2. 5.2解决中文乱码

    在处理中文字符时,可能会遇到乱码问题,这通常与字符编码设置不当有关。解决这个问题需要深入理解HTTP协议、Java I/O流以及Struts 2框架的配置。 首先,我们需要了解乱码产生的原因。在Web应用中,数据在网络传输...

    web开发各种乱码处理

    在Web开发过程中,中文乱码问题是开发者经常遇到的挑战之一,尤其在处理用户输入、页面显示以及数据库交互时。本文将全面解析Web开发中的乱码处理方法,旨在帮助开发者彻底解决中文乱码问题。 ### 一、理解乱码产生...

    jsp页面乱码处理

    对于运行在Tomcat服务器上的应用,还需要检查服务器的配置,特别是在`Connector`元素中设置`URIEncoding`属性。 ```xml connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/&gt; ``` #### 解决...

    Tomcat PostGet 中文編碼處理方法

    在处理GET请求时,中文乱码问题尤为突出。 ##### 2.1 修改Tomcat配置 为了处理GET请求中的中文乱码问题,可以通过修改Tomcat的`server.xml`文件来实现。具体步骤如下: 1. 打开`server.xml`文件,定位到`...

    struts2配置文件传值中文乱码

    在IT领域,特别是Web开发中,遇到中文乱码问题是相当常见的,尤其是在使用Struts2框架进行项目开发时。本文将围绕“Struts2配置文件传值中文乱码”这一主题,深入探讨其成因、解决方案以及相关的配置细节,旨在帮助...

    jsp传参 servlet接收中文乱码问题的解决方法.docx

    在 server.xml 文件中添加 URIEncoding="UTF-8" 属性,以便 Tomcat 能够正确地处理 UTF-8 编码的请求。 第三步:配置项目的过滤器。在 web.xml 文件中添加 CharacterEncodingFilter,以便对所有的请求和响应进行...

    struts2的中文乱码问题解决

    2. **Action乱码**:在处理表单提交等数据交互时,服务器端接收到的数据出现乱码。 3. **数据库乱码**:存储在数据库中的中文字符变为乱码。 #### 二、乱码产生的原理 Java使用Unicode编码,而Windows系统通常使用...

    有关乱码WEB乱码

    在Web开发中,字符编码问题常常导致乱码出现,尤其是在处理国际化或多语言网站时更为常见。乱码现象不仅影响用户体验,也可能会造成数据处理上的错误。本文将深入探讨Web乱码的成因及解决方案,特别是针对Struts2...

    解决Tomcat修改get提交请求乱码问题

    本文主要讨论如何解决Tomcat在处理GET提交请求时出现的乱码问题。 首先,我们要明白GET请求与POST请求的区别。GET请求通常用于获取资源,而POST请求则用于向服务器发送数据。对于POST请求,Spring框架提供了`...

    SpringMVC解决GET请求时中文乱码的问题.rar

    浏览器在构建这个URL时,会按照默认的字符集(非UTF-8)对中文参数进行编码,而Spring MVC在处理请求时,默认可能并未正确设置解码方式。 2. 字符编码:HTTP协议允许服务器和客户端之间约定字符编码,但如果没有...

    解决jsp中文乱码问题

    在JSP(web应用的一种技术)开发过程中,中文乱码问题是开发者常常遇到的问题之一,特别是在处理用户提交的数据时。本文将详细介绍如何解决JSP中中文乱码的问题,包括页面传递中文参数时可能出现的乱码情况。 #### 一...

    java项目编译时中文乱码解决

    这主要涉及到字符编码的设置和处理,不正确的编码配置可能导致在显示或处理包含中文字符的文件时出现乱码。以下是一些针对Java项目编译时中文乱码问题的解决方案。 1. **IDE设置** - **Eclipse**:在Eclipse中,...

    解决post get 请求乱码问题

    在 Web 开发中,POST 和 GET 请求可能会出现乱码问题,导致中文参数无法正确传输和解析。今天,我们将讨论如何解决 POST 和 GET 请求乱码问题。 解决 POST 请求乱码问题 在 Spring 框架中,我们可以使用 ...

    struts之中文乱码问题

    在处理中文字符时,Struts可能会遇到乱码问题,这主要是由于字符编码不一致或未正确配置导致的。下面我们将深入探讨这个问题,并提供解决策略。 **乱码产生的原因** 1. **请求编码不一致**:当用户通过表单提交...

    sshz中文乱码解决方法

    在开发过程中,经常会遇到字符编码的问题,特别是在处理中文字符时。本文主要介绍如何解决SSH框架中的中文乱码问题。针对不同的应用场景,我们可以通过以下几种方式来解决: #### 1. 强制转换字符集 在Java程序中...

    apache-tomcat-7.0.103.rar

    2. **Tomcat编码设置**: 默认情况下,Tomcat可能使用不同的字符集来处理HTTP请求和响应,这可能导致在处理非ASCII字符(如中文)时出现乱码。UTF-8是一种广泛接受的字符编码,支持世界上大多数语言,包括中文。 3. ...

    j2ee中文乱码问题终极解决之道

    1. 修改J2EE容器配置:例如Tomcat的`server.xml`,在`&lt;Connector&gt;`标签中设置`URIEncoding`属性为相应的中文编码(如GBK或GB2312),确保URL参数的正确解码。 2. 字符串编码转换:在接收数据时,使用`getBytes()`和...

Global site tag (gtag.js) - Google Analytics