乱码问题总结
一、Response发送数据时可能导致乱码:
1、Response.getOutputStream().write("中国".getBytes()) ;
这里默认用平台字节码进行编码,发送给浏览器(浏览器默认的也 是用平台字节码进行编码)。如果浏览器不是使用默认的编码格式(如果使用 utf-8),那么在输出数据时也要选择要使用的编码格式进行编码:
response.getOutputStream().write("中国".getBytes("utf-8")) ;
2、response.getWriter().write("中国");
这里默认使用iso-8859-1 编码集进行编码,所以使用该方法最容易 导致乱码,在使用字符流输出数据时,要在获取字符流对象前手动进行编码 设置: response.setContentType("text/html;Charset=utf-8") ; 或者: response.setCharacterEncoding("gbk") ;
|——注意:使用response.setCharacterEncoding("gbk") ;时 设置的编码格式和系统默认的则只需要上述一条语句。
否则还要加上: response.setCharacterEncoding("utf-8") ;
response.setHeader("Content-Type", "text/html;Charset=utf-8");
所以:为了方便一般设置:response.setContentType("text/html;Charset=utf-8") ;即可
二、Request 获取请求参数时可能导致乱码:
浏览器发送的请求参数使用的编码就是打开网页时使用的编码,而服 务器获取发送过来的请求参数默认使用 ISO-8859-1 进行解码操作,所以这过 程中可能导致乱码:
1、对于Post方式提交的数据:
可以设置request.setCharacterEncoding("utf-8");来明确指定获取 参数时使用的编码,但是此种方法只对Post 方式提交的数据有用;即是只对 请求体有用。
2、对于Get方法提交的数据:
只能手动解决乱码: String str = new String(name.getBytes("ISO8859-1"),"gbk") ;
3、通过配置tomcat的servlet.xml 配置:
在tomcat的server.xml中可以配置http连接器的URIEncoding可以指定 服务器在获取请求参数时默认使用的编码,从而一劳永逸的决绝获取请求参数时 的乱码问题。也可以指定useBodyEncodingForURI参数,令request.setCharacterEncoding也 对GET方式的请求起作用,但是这俩属性都不推荐使用,因为发布环境往往不允许修改此属性。
三、URL中包含中文时可能出现乱码:
解决方法URL编码:
1、由于HTTP协议规定,URL路径只能存在ASCLL码中的字符,所以如果URL中存在中文或特殊字符需要进行URL编码。
2、编码原理:
将空格转换为加号(+)
对0-9,a-z,A-Z之间的字符保持不变
对于所有其他的字符,用这个字符的当前字符集编码在内存中的十六进制格式表示,并在每个字节前加上一个百分号(%)。如字符“+”用%2B表示,字符“=”用%3D表示,字符“&”用%26表示,每个中文字符在内存中占两个字节,字符“中”用%D6%D0表示,字符“国”用%B9%FA表示调对于空格也可以直接使用其十六进制编码方式,即用%20表示,而不是将它转换成加号(+)
说明:
如果确信URL串的特殊字符没有引起使用上的岐义或冲突你也可以对这些字符不进行编码,而是直接传递给服务器。例如,http://jbelial.cnblogs.com?name=中国&password=123
如果URL串中的特殊字符可能会产生岐义或冲突,则必须对这些特殊字符进行URL编码。
例如,服务器会将不编码的“中+国”当作“中国”处理。还例如,当name参数值为“中&国”时,如果不对其中的“&”编码,URL字符串将有如下形式:http://jbelial.cnblogs.com?name=中&国&password=123,应编码为:http://jbelial.cnblogs.com?name=中%26国&password=123 http://jbelial.cnblogs.com/index.html#section2可改写成http://jbelial.cnblogs.com%2Findex.html%23section2
3、在Java中进行URL编码和解码: URLencoder.encode("中文","utf-8") ; URLDecoder.decode(str,"utf-8") ;
四、JSTL : c:redircet 标签内的 c:param 标签自动编码后,在重定向页面要进行手动解码。
五、在往数据库存入数据时,往外里面存储数据会出现乱码:
mysql > show variables like 'charact%' ;
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ |
+--------------------------+---------------------------------------------------------+
原因:在安装数据库时,我们选择的是默认为utf-8 编码集;所以,数据库服务器,默认我们写入数据时即客户端也是用的utf-8 编码集;所以当客户端gbk进行编码,而服务器则以utf-8编码进行解码,所以会出现乱码。
解决办法:
1、set names 当前客户端编码集;
2、主要是解决:character_set_client ,character_set_connection 该两个字段名的值。
set character_set_client gbk ;
set character_set_connection gbk ;
character_set_results 则是设置dos端显示的编码集。
-------------------------------------------------------------------------------更新时间:2013年7月11日 19:25:57
六、对全站中文乱码问题的解决办法——Filter
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 /** 12 * 全站同一编码 13 * @author 贺佐安 14 * 15 */ 16 public class SetCharacterEncoding implements Filter { 17 private FilterConfig filterConfig = null ; 18 //获取初始化的FilterConfig对象 19 public void init(FilterConfig filterConfig) throws ServletException { 20 this.filterConfig = filterConfig ; 21 } 22 23 public void doFilter(ServletRequest req , ServletResponse resp , 24 FilterChain chain) throws IOException, ServletException { 25 HttpServletRequest request = (HttpServletRequest) req ; 26 HttpServletResponse response = (HttpServletResponse) resp ; 27 28 //获取初始化的字符编码 29 String encoding = filterConfig.getInitParameter("Encoding") ; 30 request.setCharacterEncoding(encoding) ; 31 response.setCharacterEncoding(encoding) ; 32 response.setContentType("text/html;charset="+encoding) ; 33 34 MyHttpServletRequest myRequest = new MyHttpServletRequest(request) ; 35 chain.doFilter(myRequest, response) ; 36 } 37 38 public void destroy() { 39 40 } 41 }
在设置同一编码时,不要把编码写死,写在配置文件中。当然,要用Filter 进行过滤的话要对HttpServletRequest 接口进行包装:目的是解决get方式提交也不会出现乱码问题。
代码如下:
1 import java.io.UnsupportedEncodingException; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletRequestWrapper; 5 /** 6 * 包装HttpServletRequest 类,为了解决全站乱码问题 7 * @author 贺佐安 8 * 9 */ 10 public class MyHttpServletRequest extends HttpServletRequestWrapper { 11 public MyHttpServletRequest (HttpServletRequest request) { 12 super(request) ; 13 } 14 15 //对getParameter方法进行修饰: 主要是为了解决用户使用get方式提交的情况 16 public String getParameter(String name) { 17 //如果是get方法则手动解码 18 if("get".equalsIgnoreCase(super.getMethod())) { 19 String value = super.getParameter(name) ; 20 try { 21 return new String (value.getBytes("ISO-8859-1"),super.getCharacterEncoding()) ; 22 } catch (UnsupportedEncodingException e) { 23 e.printStackTrace(); 24 } 25 } 26 return super.getParameter(name); 27 } 28 }
当然还要不要忘记配置web.xml:
1 <!-- 全站中文乱码过滤器:开始 --> 2 <filter> 3 <filter-name>SetCharacterEncoding</filter-name> 4 <filter-class>filter.SetCharacterEncoding</filter-class> 5 <!-- 设置全站的编码--> 6 <init-param> 7 <param-name>Encoding</param-name> 8 <param-value>UTF-8</param-value> 9 </init-param> 10 </filter> 11 <filter-mapping> 12 <filter-name>SetCharacterEncoding</filter-name> 13 <url-pattern>/*</url-pattern> 14 </filter-mapping> 15 <!-- 全站中文乱码过滤器:结束 -->
-------------------------------------------------------------------------------更新时间:2013年7月21日 22:08:13
<总结ing...................................>