虽然计算机对英文字符的支持非常不错,我们也恨不得写的程序只会处理英文的数据,但是昨为中国人,无可避免地要处理一些中文字符。当很简单的一件事情,遇到了中文,一切就不同了!本文就会讲述实际生产环境中遇到的四个中文迷题,欢迎大家参与补充!

1、“我”讲的其它机器听不懂?

当把一串中文字符,通过HTTP、TCP方式传递到另外一个系统时,会经常惊奇地发现,在发送前还是好好的,但是收到后却全坏了!怎么办?下面提供几种情况,对症下药:

(1)发送时使用的GET请求

要特别注意传递参数时,不要直接使用中文(如?key=热情),这基本就宣告了这个代码在某个浏览器、某个机器上,对方收到的东西就是乱码了。必须要对传递的参数进行Url Encode,接受方再进行Url Decode,取出来的数据基本就是OK的了。注:某些Java框架(如Spring)的RestTemplate会自动对GET方式的调用参与进行Encode、Decode,你就可以不用再人工去做了。

(2)使用了byte传递数据

在使用MQ、原生Socket等场景下,有时要用byte传递数据。这时一定要对String的getBytes方法传递编码参数,一般用"UTF-8",且接收方则用new String(bytes, "UTF-8")来构造字符串,不然也有乱码风险!建议对需要用byte传递数据的场景,尽量转为Base64编码的方式进行传递,更方便去调试程序。

(3)设置运行环境编码

如果你的系统默认编码未设置对,那么默认的Java代码运行环境也不对,所以一要在程序运行时对Java代码运行环境进行设置。以Linux Shell为例,在启动应用的shell里,增加

export LANG=en_US.UTF-

这可以保证应用在调用系统命令行时,运行环境是以UTF-8编码的。另外如果是Tomcat,那么的脚本处也加上参数项:

-Dsun.jnu.encoding=UTF- -Dfile.encoding=UTF- -Duser.language=en -Duser.country=US

再修改tomcat默认编码(ISO-8859-1)方法,修改tomcat根目录的conf下的server.xml,Connector元素添加URIEncoding="UTF-8"属性:

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

这可以保证应用的Java代码的默认运行是在UTF-8编码基础上的,如果需要通信的系统全设置为UTF-8,可以避免诸多编码转换!

2、浏览器不认识“我”?

一般来说,浏览与应用的交互就是GET、POST请求了,当然还有PUT、DELETE请求,不过触类旁通,不需要讲太多。

POST请求的中文数据,经常是可以正常在前后台传递的,但是GET请求就没那么幸运了,一定要记得进行URL Encode与Decode,养成好的编码习惯,减少后续调试代码的难度与时间。

3、猜一猜“我”说的是什么?

在读写含中文文本的文件时,有时候也会读出乱码来,原因是因为程序的运行编码永远只有默认的一种的,那么如果不带编码参数地去读取文件,由于文件编码可能与程序编码不同,最后读出来的就是乱码了。这个时候,就需要写程序去“猜”文件的编码了。

现在有许多开源的识别编码的类库可以直接使用,但是也并不全是ok的,常见的编码能识别就好,像这些:UTF-8、GB2312、GBK、GB18030、UTF-16、US-ASCII、Big5、ISO-8859-1,遇到的概率非常大。我这里推荐几个:EncodingDetecotrjChardet

在读取到byte后,通过编码识别再存为相应的String,就可以得到正常的中文了。

4、听说UTF-8还有BOM?

BOM,在UCS编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF,这就是所谓的BOM头了,它的UTF-8编码是EF BB BF。在Windows系统上,默认用记事本存储为UTF-8格式,是有BOM的,但是Linux下却是默认无BOM的。缺了BOM的文件,经常在Windows下就识别出现错位、乱码等问题。解决之道就是在读取文件、byte的前几个字节,如果无BOM就给它加上BOM。

     /**
* 判断文件是否有BOM
*
* @return
*/
public static boolean hasBom(File file) {
FileInputStream input = null;
try {
input = new FileInputStream(file);
byte[] buf = new byte[1024];
if ((input.read(buf, 0, 1024)) != -1) {
if (buf[0] == (byte) 0xEF && buf[1] == (byte) 0xBB && buf[2] == (byte) 0xBF) {
return true;
}
}
return false;
} catch (IOException e) {
_logger.error(e);
return true;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
_logger.error("资源释放失败!", e);
}
}
}
}

如果无BOM,则在传给Windows的地方或需要导出的地方这前先加上:new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF} 这些字节。

以上这些点如果注意了,常见的中文编码问题就解决了,如果还有新的坑,博主会在此更新哈。

转载请注明原址:http://www.cnblogs.com/lekko/p/4943581.html

Java中文字符处理的四大迷题的更多相关文章

  1. Java 中文字符判断 中文标点符号判断

    Java Character 实现Unicode字符集介绍  CJK中文字符和中文标点判断 主要内容: 1. Java Character类介绍: 2. Unicode 简介及 UnicodeBloc ...

  2. Java中文字符所占的字节数

    Java语言中,中文字符所占的字节数取决于字符的编码方式,一般情况下,采用ISO8859-1编码方式时,一个中文字符与一个英文字符一样只占1个字节:采用GB2312或GBK编码方式时,一个中文字符占2 ...

  3. 使用Java判断字符串中的中文字符数量

    Java判断一个字符串str中中文的个数,经过总结,有以下几种方法(全部经过验证),可根据其原理判断在何种情况下使用哪个方法: 1. char[] c = str.toCharArray(); for ...

  4. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  5. java中Cookie中文字符乱码问题

    如果Cookie中的Value 中有中文字符出现,在加入Cookie的时候,会出现下面的错误: java.lang.IllegalArgumentException: Control characte ...

  6. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)—–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  7. Java中读取txt文件中中文字符时,出现乱码的解决办法

    这是我写的一个Java课程作业时,遇到的问题. 问题描述: 我要实现的就是将txt文件中的内容按一定格式读取出来后,存放在相应的数组. 我刚开始运行时发现,英文可以实现,但是中文字符就是各种乱码. 最 ...

  8. JAVA的中文字符乱码问题

    来源:http://luzefengoo.blog.163.com/blog/static/1403593882012754428536/ JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用 ...

  9. Java判断中文字符

    package com.jsoft.test; import java.util.regex.Pattern; /** * 判断中文字符 * * @author jim * @date 2017-12 ...

随机推荐

  1. CSS知识总结(八)

    CSS常用样式 8.变形样式 改变元素的大小,透明,旋转角度,扭曲度等. transform : none | <transform-function> <transform-fun ...

  2. Android中通过ActionBar为标题栏添加搜索以及分享视窗

    在Android3.0之后,Google对UI导航设计上进行了一系列的改革,其中有一个非常好用的新功能就是引入的ActionBar,他用于取代3.0之前的标题栏,并提供更为丰富的导航效果.Action ...

  3. CentOS7之按时间段截取指定的Tomcat日志到指定文件的方法

    CentOS7之按时间段截取指定的Tomcat日志到指定文件的方法 sed -n '/2016-11-02 15:00:/,/2016-11-02 15:05:/p' catalina.out > ...

  4. 怎样两个月完成Udacity Data Analyst Nanodegree

    在迷恋数据科学很久后,我决定要在MOOC网站上拿到一份Data Science的证书.美国三个MOOC网站,Udacity上的课程已经被分成了数个nanodegree,每个nanodegree都是目前 ...

  5. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  6. Mono+Jexus部署C# MVC的各种坑

    如果你看到这篇文章,先别急着动手,过完一遍,确定是你要的再动手. 别人提到的这里不赘述,只说查了好久才知道的. 1号坑:System.IO.FileNotFoundException Could no ...

  7. 微软收购Xamarin,你怎么看?

    今天的最大新闻就是微软收购热门初创企业Xamarin,从网上的反馈大部分都是积极的,也有担心微软在把Xamarin移动开发技术整合进VS的同时,还很有可能废掉MONO的GUI客户端能力只保留.net ...

  8. HTML5- Canvas入门(五)

    今天要介绍的是canvas对图形对象的操作,包括图像.视频绘制,和操作像素对象的方法. 图片/视频的绘制 在canvas中,我们可以通过 drawImage() 的方法来绘制图片或视频文件,其语法为: ...

  9. 完成C++不能做到的事 - Visitor模式

    拿着刚磨好的热咖啡,我坐在了显示器前.“美好的一天又开始了”,我想. 昨晚做完了一个非常困难的任务并送给美国同事Review,因此今天只需要根据他们提出的意见适当修改代码并提交,一周的任务就完成了.剩 ...

  10. UML类图(下):关联、聚合、组合、依赖

    前言 上一篇文章UML类图(上):类.继承.实现,讲了UML类图中类.继承.实现三种关系及其在UML类图中的画法,本文将接着上文的内容,继续讲讲对象之间的其他几种关系,主要就是关联.聚合.组合.依赖, ...