一 原理:
编码是信息从一种形式或格式转换为另一种形式的过程也称为计算机编程语言的代码简称编码。比如:将文本文件转换成计算机存储的二进制数据时的过程。
解码,是编码的逆过程。比如:将二进制数据转换成文本文件的过程。
二 乱码的产生:
编码产生的原因是因为编码的方式和解码的方式不相同导致的;比如存储html文件时按照gbk存储 打开时按照utf-8打开就会出现乱码。
三、乱码产生的情况
1. 将文件导入到eclipse时:
2. 客户端到服务器(发送请求时)
2.1通过get方式产生的乱码:a:
这样就可解决get方式乱码的请求了。
b:
11 byte [] bs = name.getBytes("ISO8859-1");//内部编码字节流,按照 //默认的编码解码
12 String name name = new String(bs,"UTF-8"); //按照utf-8编码
c:
当URL地址里包含非西欧字符的字符串时,系统会将这些字符转换成application/x-www-form-urlencoded字符串。
然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。这个时候我们就要使用另一种编码类型“multipart/form-data”,比如在我们在做上传的时候,表单的enctype属性一般会设置成“multipart/form-data”。
//将application/x-www-form-urlencoded字符串
//转换成普通字符串
//必须强调的是编码方式必须正确,如baidu的是gb2312,而google的是UTF-8
String keyWord = URLDecoder.decode("%E6%96%87%E6%A1%A3", "gb2312");
System.out.println(keyWord);
//将普通字符串转换成
//application/x-www-form-urlencoded字符串
//必须强调的是编码方式必须正确,如baidu的是gb2312,而google的是UTF-8
String urlStr = URLEncoder.encode("文档", "gb2312");
System.out.println(urlStr);
d: ajax中get请求的中文乱码
只需要在script中添加setRequestHeader("Content-Type","text/html; encoding=gb18030")
2.2通过post方式产生的乱码
对于Post请求,只需在Servlet或者jsp中写入如下代码就可以把解决从表单中传入的中文乱码问题 request.setCharacterEncoding("utf-8");
ajax对于使用POST,JSP的解决方法如下:
使用escape(或encodeURI,两个函数都是JavaScript的函数,功能基本相同,可以查一下相关的帮助),但要使用两次,这个是关键。
在 web.xml 中配置 filter ,具体配置如下页:
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3服务器到客户端的乱码
3.1 servlet 中到客户端
response.setContentType("text/html; charset=UTF-8");
//或者
response.setCharacterEncoding("UTF-8");
3.2 jsp到客户端
如果.jsp文件有<%@ page language="java" pageEncoding="UTF-8"%>,则eclipse会自动存为UTF-8方式,不管eclipse的encoding是什么;
contentType="text/html;charset=UTF-8"表示当浏览器得到此文件时以什么方式解码:
<%@ page language="java" contentType="text/html; charset=utf-8" %>
3.3 html 通用
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
3.4 其他
//设置编码编码 方式一
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("UTF-8");*/
//设置编码方式二:(相当于request 和response设置编码)
response.setContentType("text/html;charset=UTF-8");
4 ide项目发布到web服务器时产生乱码:
4.1 在TOMCAT中的server.xml中的
<Connector中添加两个设置useBodyEncodingForURI="true" //设置POST和GET使用相同编码
URIEncoding="UTF-8" //对URI使用utf-8编码处理
<Connector useBodyEncodingForURI="true" URIEncoding="UTF-8" connectionTimeout="20000" maxThreads="150" port="8888" protocol="HTTP/1.1" redirectPort="8443"/>
4.2 配置如图所示:
4.3 配置 meta
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5 服务器到数据库产生乱码
5.1 设置连接字符串的url传入参数编码:jdbc:mysql://localhost:3306/db_name?useUnicode=true&charaterEncoding=utf-8,
5.2 设置mysql编码
1). 首先查看系统的字符集和排序方式: SHOW VARIABLES LIKE ''character_set_%'';
2). 1 在my.cf文件的段设置:
default-character-set=utf8
这条语句的作用是把character_set_client, character_set_connection_,character_set_results 设定为utf8,包括对应的排列方式的 编码。
Character_set_server是系统编码,这个是不用改的。
当然改变character_set_client, character_set_connection_,character_set_results 编码方式的另外一种方法是:SET NAMES “UTF8”;
它的作用相当于:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
2. 改变数据库的编码方式: alter database databasename character set utf8;或者
SET character_set_client = utf8;
3. 不管你是web编程还是桌面编程,你的数据库的连接地址url中,一定要后 缀:?useUnicode=true& characterEncoding=utf- 8/hibernate?useUnicode=true&characterEncoding=utf-8
六 从数据库到 web服务器乱码
6.1 jsp设置pageEncoding
<%@ page language="java" pageEncoding="gb2312"%>
注:pageEncoding的内容只是用于jsp输出时的编码,不会作为header发出去的。
6.2 特别的: 如果存入时按照一种编码,取出数据还是使用这种编码就不会出现乱码,即使在数据库中是乱码,也能读出。
七 服务器端的乱码
当导入sql文件时保证和数据库的编码格式一致,如果不一致可使用文本工具作为中转站(作用:修改编码)。
导入数据时,如果目标数据库或表是UTF-8字符集的,而导入SQL中有中文,可能在最终结果中出现乱码,此时只需在导入的SQL文件第一行加入如下内容 即可。
/*!40101 SET NAMES utf8 */;但是在source 命令前输入set names utf8,然后再用source命令导入脚本,中文乱码就解决了
八 IO流乱码
一、
IO的乱码往往出现字符流中,可在字节流向字符流转换的时候处理;
new InputStreamReader(new FileInputStream(file),"UTF-8")。
二、直接使用字节流
//在创建时可以指定字符集
public InputStreamReader(InputStream in, String charsetName){
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
}
//如果没有指定则获取默认值
public static StreamDecoder forInputStreamReader(InputStream inputstream, Object obj, String s){
String s1 = s;
if(s1 == null)
s1 = Converters.getDefaultEncodingName();
if(!Converters.isCached(0, s1))
。。。
}
//默认值来自System.getProperty
public static String getDefaultEncodingName(){
GetPropertyAction getpropertyaction = new GetPropertyAction("file.encoding");//这里取自System.getProperty(变量)
return defaultEncoding;
}
System.getProperty值的来源:首先并不是操作系统os的默认编码
问题1:file.encoding的值是什么呢? 这个一开始我认为是操作系统的编码
但我错了它的值为保存每个程序的main入口的那个java文件的保存编码(点击文件-->属性-->text file encoding(other的值),这是使用eclipse 编译器)。
怡清 总结于
2013 年 03月 08日