Java编码问题原因以及解决
一、文件编码
Unicode 是首选编码。Unicode 是全球范围的字符编码标准。
小结: GBK 与unicode之间的转换是通过gbk unicode映射表。
UTF-8 与unicode之间的转换是通过转换规则公式
所以说,unicode是核心中介。Gbk要转换成utf-8的话,先转成unicode。然后unicode再转换成utf-8;反之亦然。
二、XML编码问题
★ 编码属性应当被指定为文档被保存时所使用的编码
★ encoding声明的编码属性
★ W3C定义了三条XML解析器如何正确读取XML文件的编码的规则:
1.如果文挡有BOM(字节顺序标记,一般来说,如果保存为unicode格式,则包含BOM,ANSI则无),
就定义了文件编码(另存为文件时,选择的编码格式)。
2.如果没有BOM,就查看XML encoding声明的编码属性。
3.如果上述两个都没有,就假定XML文挡采用UTF-8编码
★ Eclipse等编辑器会根据XML encoding声明的编码属性来保存文件。
★移除无效的XML字符
/** * 移除无效的XML字符
* 官方定义了XML的无效字符分为三段: 0x00 - 0x08 0x0b - 0x0c 0x0e - 0x1f
* @param value
* @return */
public static String removeInvalidXMLCharacter(String value) {
return value.replaceAll("[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]", "");
}
三、String编码问题
★ 对于 String s = "你好哦!";的理解。
1、如果源码文件是GBK编码, 操作系统(windows)默认的环境编码为GBK,那么编译时, JVM将 按照GBK编码将字节数组解析成字符,然后将字符转换为unicode格式的字节数组,作为内部存储。
如果源码文件是UTF-8编码, 我们需要通知编译器源码的格式,javac -encoding utf-8 ... , 编译时,JVM按照utf-8 解析成字符,然后转换为unicode格式的字节数组,
那么不论源码文件是什么格式,同样的字符串,最后得到的unicode字节数组是完全一致的,显示的时候,也是转成GBK来显示(跟OS环境有关)
2、System.out.println( new String(s.getBytes(),"UTF-8")); // 错误,因为getBytes()默认使用GBK编码, 而解析时使用UTF-8编码,肯定出错。
★如何正确的将GBK转UTF-8 ? (实际上是unicode转UTF-8)
注意:并不算new String( s.getBytes("GBK") , "UTF-8); //源码文件是GBK格式,或者这个字符串是从GBK文件中读取出来的, 转换为string 变成unicode格式
//字符串在内存中是unicode格式
String gbkStr = "你好哦!"; //利用getBytes将unicode字符串转成UTF-8格式的字节数组
byte[] utf8Bytes = gbkStr.getBytes("UTF-8"); //然后用utf-8 对这个字节数组解码成新的字符串
String utf8Str = new String(utf8Bytes, "UTF-8");
即:new String( s.getBytes("utf-8") , "utf-8");
★new String(s.getBytes("iso-8859-1") ,"GBK")
一般用来转换原来是GBK编码的,被转换成了iso-8859-1,现在恢复回GBK。
注意:并不是所有转换都是可逆的,iso-8859-1的字节数组是单字节的,所以能转换。
★读写时,可以指定编码
四、JAVA编码问题
★文件加载
java文件编码格式:默认与操作系统一致,但可修改。
编译成Class文件:class文件的编码固定为UTF-8
load class文件到JVM :Unicode
内存:Unicode
理解:不管文件的编码格式是什么,加载到JVM都是一样的。
★网络传输都是以字节为单位,所以所有的数据都必须能够被序列化为字节。在 Java 中数据被序列化必须继承 Serializable 接口。
★从网络中读取资源文件的时候,无论当前java文件编码为何值,得到的一个个字节只与读取的资源文件保存的编码有关。
★对于读取网络资源乱码问题,如果能够知道资源的编码格式,只需要在转成字符串的过程中使用这种编码就行。
所以,关键问题落在了判断资源文件编码方式是那种。
五、encodeURI与encodeURIComponent
★对于不同浏览器编码有些不同,所以需要编码。两者都是使用UTF-8编码规则来编的
★区别,encodeURI用于整个URL ,对于url里面的预留符号等不进行编码;encodeURIComponent用于参数段,编码更彻底:url里面的预留符号等会编码。
★两次编码的问题。
(1)如果服务器的编码是UTF-8,那么下面是不会出现乱码的。否则,出现乱码。
前端:var url1=encodeURI(url);
后台:String name=request.getParameter("name");
(2)不管服务器编码,都不会出现乱码
前端:url1=encodeURI(url);把url中的中文编为ASCII码。
url2=encodeURI(url1);对ASCII码进行编码
后台://这里tomcat自动解码。tomcat的配置文件没设置,那么默认是ISO-8859-1
String name1=request.getParameter("name");
String name2 = java.net.URLDecoder.decode(name1,"UTF-8");
不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到url1。因为ASCII码的编码用GBK、UTF-8、ISO-8859-1编码的结果是相同的。
★对于POST提交数据,浏览器会根据网页的ContentType("text/html; charset=GBK") 中指定的编码进行对表单中的数据进行编码。
服务端:request.setCharacterEncoding()设置编码,然后通过request.getParameter获得正确的数
六、JAVA中的乱码
★浏览器用utf-8解析:
(手动)==> 在浏览器中右键选择编码格式为utf-8
(智能)==> 在文件中写入如: <meta name="content-type" content="text/html; charset=UTF-8">
通过<meta>标签模拟response头,起到告诉浏览器用utf-8的编码解析
(智能)==> response.setContentType("text/html;charset=utf-8");
或 response.setHeader("content-type","text/html;charset=UTF-8");
或 response.getOutputStream().write("<meta http-equiv='content-type' content='text/html;charset=utf-8'>".getBytes());
目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码
常用:
<meta name="content-type" content="text/html; charset=UTF-8">或<meta charset="utf-8">
<%@ pageEncoding="utf-8"%>
<?xml encoding="UTF-8"?>
★response.setCharacterEncoding("UTF-8"); 设置的是response存储数据的码表。 目的是用于response.getWriter()输出的字符流的编码。
如果是response.getOutputStream()是不需要此种解决方案的,因为这句话的意思是为了将response对象中的数据以UTF-8解码后的字节流发向浏览器
★response.setContentType("text/html;charset=utf-8");内部也调用了setCharacterEncoding方法,相当于setCharacterEncoding("UTF-8");和setHeader("content-type","text/html;charset=UTF-8");
★response.setCharacterEncoding可以覆盖之前的response.setContentType
★ 1.IE和WEB服务器默认通过ISO-8859-1进行编码,可以使用setCharacterEncoding是设置字符的编码
2.URL默认只支持ISO-8859-1
★ Get请求:参数QueryString内容默认编码方式问ISO8859-1,而且使用request.setCharacterEncoding("utf-8")也无法解决问题。
1.修改tomcat服务器的配置文件<Connector>节点 URIEncoding="utf-8"
2.如果没有设置URIEncoding,那么使用new String(username.getBytes("ISO-8859-1"),"UTF-8");
3. useBodyEncodingForURI=”true”:使用Header中ContentType中定义的Charset
4.url、cookie、ajax get请求,一般用URLEncoder
★ Post请求 request.setCharacterEncoding("UTF-8"); 只对Post请求有效
Java编码问题原因以及解决的更多相关文章
- Java Web乱码原因与解决
Java Web乱码原因与解决 一.了解编码常识: 1.ASCII 码 众所周知,这是最简单的编码.它总共可以表示128个字符,0~31是控制字符如换行.回车.删 除等,32~126是打印字符,可以通 ...
- Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- Java并发编程:Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- 【转】Java ConcurrentModificationException异常原因和解决方法
原文网址:http://www.cnblogs.com/dolphin0520/p/3933551.html Java ConcurrentModificationException异常原因和解决方法 ...
- 9、Java ConcurrentModificationException异常原因和解决方法
Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...
- (转)Java ConcurrentModificationException异常原因和解决方法
转载自:http://www.cnblogs.com/dolphin0520/p/3933551.html 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会 ...
- Java ConcurrentModificationException异常原因和解决方法(转)
摘自:http://www.cnblogs.com/dolphin0520/p/3933551.html#undefined 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同 ...
- [Java] CPU 100% 原因查找解决
CPU 100%肯定是出现死锁,这个时候观察内存还是够用的,但是CPU一直100%,以下几步解决: 1. 找到进程消耗cpu最大的 $top top - :: up days, :, user, lo ...
- java线程安全问题原因及解决办法
1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...
随机推荐
- git的问题(error: object file .git/objects/* is empty...)的解决方案及对git版本库文件的了解
由于操作不当,导致git版本库出了大问题,如下所示: error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e ...
- apply()方法和call()方法
obj.func.call(obj1) //是将obj1看做obj,调用func方法,将第一个参数看做函数调用的对象,可以看做,将obj的方法给obj1使用 ECMAScript规范给所有 ...
- 【转载】javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- ES6入门——正则的扩展
1.RegExp构造函数 在ES5中,RegExp构造函数的参数有两种情况.第一种情况是参数是字符串,这时第二个参数表示正则表达式的修饰符:第二种情况是,参数是一个正则表示式,这时会返回一个原有正则表 ...
- C#接收WebSphere MQ中文乱码问题
最近在用IBM的WebSphere MQ做数据传输,客户端操作系统Windows,服务器是AIX,我们用的都是UTF-8编码,但是联调时发现带中文的都出现了乱码.折腾了好久才发现问题,原来是CCSID ...
- Oracle案例04——ORA-39700: database must be opened with UPGRADE option
Oracle11.2.0.3数据库通过rman备份到Oracle11.2.0.4上做还原,报需要升级的错误,具体处理步骤如下: 一.错误信息 SQL> alter database open r ...
- 在win7 windows 上编译 beego 上传到 linux 去执行
在beego的项目目录下,执行: GOOS=linux GOARCH=amd64 go build So easy!但是却搞了好久! 参考连接:http://blog.csdn.net/changji ...
- win10下Java环境配置
JAVA_HOME : E:\ensoft\jdk(这个是jdk安装路径) CLASSPATH : .;E:\ensoft\jdk\lib;E:\ensoft\jdk\lib\dt.jar;E:\en ...
- C++中虚继承的作用及底层实现原理
http://blog.csdn.net/bxw1992/article/details/77726390
- 配置spark集群
配置spark集群 1.配置spark-env.sh [/soft/spark/conf/spark-env.sh] ... export JAVA_HOME=/soft/jdk 2.配置slaves ...