在url后面直接跟中文参数解决中文参数乱码问题

来源:互联网 发布:中英文语音翻译软件 编辑:程序博客网 时间:2024/06/08 18:17
首先要保证 页面,数据库,逻辑代码要统一格式比如我的是UTF-8


首先我们要明白两个概念;URIEncoding、useBodyEncodingForURI


URIEncoding:直接设置Parameters的queryStringEncoding的值。即针对请求参数的编码。 


useBodyEncodingForURI:设置queryStringEncoding的值=encoding的值,即请求参数采用请求体的编码方式。


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

<!DOCTYPE html><html>    <head>        <meta charset="utf-8" />        <title></title>    </head>    <body>        <form action="http://127.0.0.1:8080/string?name=中国" method="post">            <input type="text" name="user" value="张三"/>            <input type="submit" value="提交"/>        </form>    </body></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文件中配置,如下:

<Service name="Catalina">     <!--The connectors can use a shared executor, you can define one or more named thread pools-->    <!--    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"        maxThreads="150" minSpareThreads="4"/>    -->      <!-- A "Connector" represents an endpoint by which requests are received         and responses are returned. Documentation at :         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)         Java AJP  Connector: /docs/config/ajp.html         APR (HTTP/AJP) Connector: /docs/apr.html         Define a non-SSL HTTP/1.1 Connector on port 8080    -->    <Connector port="8080" protocol="HTTP/1.1"               connectionTimeout="20000"               redirectPort="8443" useBodyEncodingForURI='true' URIEncoding='UTF-8' />    <!-- A "Connector" using the shared thread pool-->
继续说说CharacterEncodingFilter的作用。 
使用方式,将如下代码加入web.xml文件中: 


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


public class CharacterEncodingFilter 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;    }      @Override    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);    } }

这个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的请求体。 



在tomcat的server.xml

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

如果还不能解决看一下http://blog.csdn.net/zhmhhu/article/details/52584633





到这里我的问题完美解决了;我主要是遇到的问题,首先我是在Tomcat的server.xml设置好了

 URIEncoding="UTF-8"
在我本地跑传的中文参数不乱码,但是部署到服务器上面后用域名浏览传参数中文乱码而用内网传中文参数是不乱码的  ,找了好久我就在URLEncoding='UTF-8'的后面添加了一句这个

useBodyEncodingForURI="true"

就莫名奇怪的好了用域名传中文参数也不会乱码了