Loading

中文乱码问题

乱码原因:
1、浏览器页面数据传递到服务器时乱码,示意为:
  页面(字符)------->自动转换为字节------->服务器(将字节转化成字符,否则乱码)
2、服务器传递数据到页面时乱码,示意为:
  服务器(字符,需要设置返回数据的中文编码,否则乱码)------->自动转换为字节------->页面(将字节按照页面指定的编码格式转化成字符)
 
详解如下:
 
1、浏览器页面数据传递到服务器时乱码
浏览器页面解读页面的编码格式可以在页面的头信息中指定,页面上的输入的字符则也是按照指定的编码格式存储,传递参数的时候会将字符转化成字节,在后台就收参数的时候需要将接收到的字节转化成字符才能操作,但是转化是默认按照ISO-8859-1的编码方式转化的,故会出现乱码问题.
get请求方式解决:
1、 String userName=new String(request.getParameter("username").getBytes("iso-8859-1 "),"utf-8");
说明:此方法表示在接受参数后重新对参数编码,故对于get方式要手动对参数逐个解码,此过程可以在过滤器中来对参数编码
2、修改Tomcat的配置,加上URIEncoding="UTF-8" :<Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000"   redirectPort="8443" URIEncoding="UTF-8"/>
注:这种方式缺点显而易见,换了服务器就要更改,有时候忘记也是很常见的事情,同时这个设置更改了tomcat下所有应用的编码格式吗,不够灵活
 
post请求方式解决:
1、request.setCharacterEncoding(“utf-8”)
说明:此方法是在接收参数前指定接收数据的编码格式。
注意:该方法只对post请求中的实体内容有效,对get请求无效,并且转码的话前提是页面指定的编码格式也要是utf-8,转码是按照页面指定的编码格式转换
 
2、服务器传递数据到页面时乱码
在服务器向浏览器发送数据时会将字符转化成字节流输送,但是默认的转化方式还是ISO-8859-1,故要指定返回数据的编码格式。
1、设置响应返回数据格式为:reponse.setCharacterEncoding(“utf-8”);reponse.setContentType("text/html"),合并写为:response.setContentType(“text/html” ;charset=utf-8)
注:
此方法针对字符流返回数据,因为字符流会按照指定的编码格式查询码表编码,但是此方法对于字节流无效,因为字节流不会去查编码表,返回的数据中如果有中文的话则中文的编码格式就是中文字符默认的编码GBK,可以通过如“hello”.getBytes(“utf-8”)指定字节流的编码格式;
浏览器接收到数据后按照浏览器页面设置的编码格式来解码,页面设置的编码格式和后台接受转码的编码格式都要一致才行;
 
在springMVC中可以设置如下:
<filter>  
    <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>

 

 
CharacterEncodingFilter源码为:
public class CharacterEncodingFilter extends OncePerRequestFilter {
    private String encoding;
    private boolean forceEncoding = false;

    public void setEncoding(String encoding) {
        this.encoding = 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);
    }
}

 

当Servlet容器启动的时候,会读取web.xml中对于过滤器的配置信息, 读取到<init-param>中的子标签<param-name>encoding和forceEncoding所对应的<param-value>的值,再通过调用该类setEncoding(String encoding)和setForceEncoding(boolean forceEncoding) 将值分别注入到encoding和forceEncoding 中。
 
forceEncoding:字面意思是强制字符集,但你大可不必按字面意思理解,因为这个参数的值只不过是指定response的字符集是否也设置成encoding所指定的字符集,所以你可以选择设置为true或false,默认值为false。
当值为true时,相当于
request.setCharacterEncoding(this.encoding);  
response.setCharacterEncoding(this.encoding);  
当值为false时,相当于:
request.setCharacterEncoding(this.encoding);  
 
故如果在web.xml中设置了此编码格式就可以不用再代码中再写这两句设置编码了
 
posted @ 2016-11-07 11:30  梦醒点灯  阅读(5347)  评论(0编辑  收藏  举报