`
JAVA海洋
  • 浏览: 618164 次
  • 性别: Icon_minigender_1
  • 来自: 太原
社区版块
存档分类
最新评论

这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享!

阅读更多
1.字节和unicode
java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式是使用字节流的。因此java要对这些字节流经行转化。char是unicode的,而byte是字节。java中byte/char互转的函数在sun.io的包中间有。其中ByteToCharConverter类是中调度,可以用来告诉你,你用的convertor。其中两个很常用的静态函数是
publicstaticByteToCharConvertergetDefault();
publicstaticByteToCharConvertergetConverter(Stringencoding);
如果你不指定converter,则系统会自动使用当前的encoding,gb平台上用gbk,en平台上用8859_1。
byte——〉char:
"你"的gb码是:0xc4e3,unicode是0x4f60
Stringencoding="gb2312";
byteb[]={(byte)'\u00c4',(byte)'\u00e3'};
ByteToCharConverterconverter=ByteToCharConverter.getConverter(encoding);
charc[]=converter.convertAll(b);
for(inti=0;i<c.length;i++){
System.out.println(Integer.toHexString(c[i]));
}
结果是什么?0x4f60
如果encoding="8859_1",结果又是什么?0x00c4,0x00e3
如果代码改为
byteb[]={(byte)'\u00c4',(byte)'\u00e3'};
ByteToCharConverterconverter=ByteToCharConverter.getDefault();
charc[]=converter.convertAll(b);
for(inti=0;i<c.length;i++){
System.out.println(Integer.toHexString(c[i]));
}
结果将又是什么?根据平台的编码而定。

char——〉byte:
Stringencoding="gb2312";
charc[]={'\u4f60'};
CharToByteConverterconverter=CharToByteConverter.getConverter(encoding);
byteb[]=converter.convertAll(c);
for(inti=0;i<b.length;i++){
System.out.println(Integer.toHexString(b[i]));
}
结果是什么?0x00c4,0x00e3
如果encoding="8859_1",结果又是什么?0x3f
如果代码改为
Stringencoding="gb2312";
charc[]={'\u4f60'};
CharToByteConverterconverter=CharToByteConverter.getDefault();
byteb[]=converter.convertAll(c);
for(inti=0;i<b.length;i++){
System.out.println(Integer.toHexString(b[i]));
}
结果将又是什么?根据平台的编码而定。
很多中文问题就是从这两个最简单的类派生出来的。而却有很多类不直接支持把encoding输入,这给我们带来诸多不便。很多程序难得用encoding了,直接用default的encoding,这就给我们移植带来了很多困难。

2.utf-8
utf-8是和unicode一一对应的,其实现很简单
7位的unicode:0_______
11位的unicode:110_____10______
16位的unicode:1110____10______10______
21位的unicode:11110___10______10______10______
大多数情况是只使用到16位以下的unicode:
"你"的gb码是:0xc4e3,unicode是0x4f60
0xc4e3的二进制:
1100,0100,1110,0011
由于只有两位我们按照两位的编码来排,但是我们发现这行不通,因为第7位不是0因此,返回"?"
0x4f60的二进制:
0100,1111,0110,0000
我们用utf-8补齐,变成:
1110,0100,1011,1101,1010,0000
e4--bd--a0
于是返回:0xe4,0xbd,0xa0。

3.string和byte[]
string其实核心是char[],然而要把byte转化成string,必须经过编码。string.length()其实就是char数组的长度,如果使用不同的编码,很可能会错分,造成散字和乱码。
例如:
Stringencoding=“”;
byte[]b={(byte)'\u00c4',(byte)'\u00e3'};
Stringstr=newString(b,encoding);  
如果encoding=8859_1,会有两个字,但是encoding=gb2312只有一个字这个问题在处理分页是经常发生。

4.Reader,Writer/InputStream,OutputStream
Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char读/写InputStream/OutputStream。
例如:
文件test.txt只有一个"你"字,0xc4,0xe3
Stringencoding="gb2312";
InputStreamReaderreader=newInputStreamReader(newFileInputStream(
"text.txt"),encoding);
charc[]=newchar[10];
intlength=reader.read(c);
for(inti=0;i<length;i++){
System.out.println(c[i]);
}
结果是什么?你
如果encoding="8859_1",结果是什么???两个字符,表示不认识。
反过来的例子自己做。

5.我们要对java的编译器有所了解
javac?encoding
我们常常没有用到encoding这个参数。其实encoding这个参数对于跨平台的操作是很重要的。如果没有指定encoding,则按照系统的默认encoding,gb平台上是gb2312,英文平台上是iso8859_1。
java的编译器实际上是调用sun.tools.javac.main的类,对文件进行编译,这个类有compile函数中间有一个encoding的变量,-encoding的参数其实直接传给encoding变量。编译器就是根据这个变量来读取java文件的,然后把用utf-8形式编译成class文件。
例子代码:
Stringstr="你";
FileWriterwriter=newFileWriter("text.txt");
write.write(str);
writer.close();

如果用gb2312编译,你会找到e4bda0的字段;
如果用8859_1编译,00c400e3的二进制:
0000,0000,1100,0100,0000,0000,1110,0011
因为每个字符都大于7位,因此用11位编码:
1100,0001,1000,0100,1100,0011,1010,0011
c1--84-- c3-- a3
你会找到c184c3a3。

但是我们往往忽略掉这个参数,因此这样往往会有跨平台的问题:
样例代码在中文平台上编译,生成zhclass
样例代码在英文平台上编译,输出enclass
(1). zhclass在中文平台上执行ok,但是在英文平台上不行
(2).enclass在英文平台上执行ok,但是在中文平台上不行
原因:
(1).在中文平台上编译后,其实str在运行态的char[]是0x4f60, 在中文平台上运行,filewriter的缺省编码是gb2312,因此chartobyteconverter会自动用调用gb2312的converter,把str转化成byte输入到fileoutputstream中,于是0xc4,0xe3放进了文件。
但是如果是在英文平台下,chartobyteconverter的缺省值是8859_1,filewriter会自动调用8859_1去转化str,但是他无法解释,因此他会输出"?"
(2).在英文平台上编译后,其实str在运行态的char[]是0x00c40x00e3,在中文平台上运行,中文无法识别,因此会出现??;
在英文平台上,0x00c4-->0xc4,0x00e3->0xe3,因此0xc4,0xe3被放进了文件。

6.其它原因:<%@pagecontentType="text/html;charset=GBK"%>
设置浏览器的显示编码,如果response的数据是utf8编码,显示将是乱码,但是乱码和上述原因还不一样。

7.发生编码的地方
?从数据库到java程序byte——〉char
?从java程序到数据库char——〉byte
?从文件到java程序byte——〉char
?从java程序到文件char——〉byte
?从java程序到页面显示char——〉byte
?从页面form提交数据到java程序byte——〉char
?从流到java程序byte——〉char
?从java程序到流char——〉byte

谢志钢的解决方法:
我是使用配置过滤器的方法解决中文乱码的:

<web-app>
<filter>
<filter-name>RequestFilter</filter-name>
<filter-class>net.golden.uirs.util.RequestFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>gb2312</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>RequestFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>


publicvoiddoFilter(ServletRequestreq,ServletResponseres,
FilterChainfChain)throwsIOException,ServletException{
HttpServletRequestrequest=(HttpServletRequest)req;
HttpServletResponseresponse=(HttpServletResponse)res;
HttpSessionsession=request.getSession();
StringuserId=(String)session.getAttribute("userid");
req.setCharacterEncoding(this.filterConfig.getInitParameter("charset"));//设置字符集?
实际上是设置了byte——〉char的encoding
try{
if(userId==null||userId.equals("")){
if(!request.getRequestURL().toString().matches(
".*/uirs/logon/logon(Controller){0,1}\\x2Ejsp$")){
session.invalidate();
response.sendRedirect(request.getContextPath()+
"/uirs/logon/logon.jsp");
}
}
else{//看看是否具有信息上报系统的权限
if(!net.golden.uirs.util.UirsChecker.check(userId,"信息上报系统",
net.golden.uirs.util.UirsChecker.ACTION_DO)){
if(!request.getRequestURL().toString().matches(
".*/uirs/logon/logon(Controller){0,1}\\x2Ejsp$")){
response.sendRedirect(request.getContextPath()+
"/uirs/logon/logonController.jsp");
}
}
}
}
catch(Exceptionex){
response.sendRedirect(request.getContextPath()+
"/uirs/logon/logon.jsp");
}
fChain.doFilter(req,res);
}
分享到:
评论

相关推荐

    在eclipse中中文汉字乱码的解决方案

    Eclipse 中中文汉字乱码的解决方案 Eclipse 是一个功能强大且广泛使用的集成开发环境(IDE),但是在使用过程中,用户可能会遇到中文汉字乱码的问题。本文将为大家分享解决 Eclipse 中中文汉字乱码的方案,以便大家...

    中文乱码问题的解决方案

    本篇文章将深入探讨中文乱码的原因、解决方案以及如何在JSP等Web开发环境中正确处理中文编码,以期为遇到类似问题的开发者提供实用的指导。 ### 中文乱码的常见原因 中文乱码问题通常源于字符集不匹配或编码转换...

    idea 控制台中文乱码和web项目乱码(csdn)————程序.pdf

    本文将深入探讨如何解决这个问题,并提供多种解决方案。 首先,我们要理解乱码问题通常发生在两个主要环节:IDEA控制台和Web服务器(Tomcat)的交互,以及Web应用内部的数据处理。在IDEA中,控制台的输出乱码可能是...

    字体显示乱码设置.txt

    通过本文档提供的解决方案,我们不仅解决了Java环境中字体乱码的问题,还深入了解了软链接的工作原理以及Java字体管理机制。这对于提高跨平台应用程序的用户体验至关重要。希望本指南能帮助开发者们更好地理解和解决...

    下载中文名称出现乱麻解决方案

    ### 下载中文名称出现乱码解决方案 #### 一、背景介绍与问题描述 在进行Java Web应用程序开发过程中,经常会遇到用户需要下载文件的情况。如果这些文件的名称包含中文字符,在某些浏览器或操作系统环境下,可能会...

    Spring MVC参数传递中文乱码解决方法分享

    一、GET 方式中文乱码解决方案 在 GET 方式中,我们可以使用以下方法来解决中文乱码问题: String str = new String(request.getParameter("参数名").getBytes("iso-8859-1"), "utf-8"); 这个方法可以将 GET ...

    jsp地址栏传中文显示乱码解决方法分享.docx

    ### JSP地址栏传中文显示乱码解决方法 在Web开发过程中,经常遇到的一个问题是当通过URL传递包含中文字符的数据时,在接收端会出现乱码的情况。这种情况尤其在使用Java Server Pages (JSP)进行Web应用开发时较为...

    中文txt文档打开后乱码怎么办?.docx

    然而,有时候我们会遇到一个问题:原本正常的中文TXT文档在另一台计算机上打开时却变成了乱码。这主要是因为不同操作系统或软件之间对中文编码的支持不同所导致的。本文将详细介绍如何解决这个问题,并提供一些实用...

    hibernate插入数据库乱码的解决方式

    ### hibernate插入数据库乱码的解决方式 在处理数据库与应用程序之间的数据交互时,经常会遇到...此外,还可以参考一些实战经验分享,比如常建功老师的视频教程,这些资料对于理解问题根源及解决方案具有很大的帮助。

    ASP.NET中Request.Form中文乱码的解决方法

    总结来说,解决ASP.NET中`Request.Form`中文乱码的问题,需要理解不同编码之间的转换,并针对性地调整发送方或接收方的编码设置。在本例中,通过在发送数据的页面设置合适的响应编码,实现了跨编码格式的数据交换,...

    spring 问题总结实用知识库分享知识分享

    springMVC ResponseBody 返回汉字乱码解决方案 在使用 SpringMVC 时,可能会出现汉字乱码错误。解决方法是,使用 SpringMVC 的编码过滤器,确保响应体的编码正确,并且确保视图文件的编码正确。 springboot 提示...

    php插入中文到sqlserver 2008里出现乱码的解决办法分享

    针对PHP插入中文到SQL Server 2008数据库出现乱码的问题,解决方法通常涉及字符编码的处理,下面详细说明解决方案所涉及的知识点。 首先,字符编码问题是编程和数据库操作中常见的问题。在使用PHP连接数据库进行...

    QT 中文显示

    QT 中文显示 QT 中文显示是指在 QT 编程软件中实现中文显示的设置方法。...本文介绍了 QT 中文显示的知识点,并提供了实践例子和解决方案。希望本文能够帮助开发者更好地理解 QT 中文显示,并能够正确地实现中文显示。

    浅谈mysql的中文乱码问题

    本文将深入探讨MySQL中文乱码问题及其解决方案。 首先,问题的出现可能源于多种因素,例如数据库、表、字段或客户端程序的字符集设置不正确。在本例中,开发者在Eclipse通过JDBC向MySQL数据库写入中文数据时遇到了...

    Python之pandas读写文件乱码的解决方法

    下面将详细探讨这个问题,并分享一些切实可行的解决方案。 首先,当我们遇到乱码问题时,一个常见的原因是文件编码格式和pandas读写时指定的编码格式不一致。在Windows系统中,文件默认保存为GBK或GB2312等编码格式...

    tableExport导出Excel/PDF/PNG/SVC/XML/JSON方法扩展

    总结来说,"tableExport导出Excel/PDF/PNG/SVC/XML/JSON方法扩展"是一个强大且全面的数据导出工具,它优化了解决方案中的多个关键问题,如Excel样式定制、PDF中文支持、PNG导出性能提升,以及对SVC和XML/JSON的支持...

    ireport快速入门指南.pdf

    6. 解决报表问题:文档列举了一些常见的报表问题以及它们的解决方案,例如中文字体乱码、PDF中无法显示、报表分栏、空值处理、背景颜色交替、格式化输出、柱状图方向、报表参数传递、不同文件格式导出、Web应用中...

    vs2012CopyToWord

    标题“vs2012CopyToWord”暗示了这是一个专门针对VS2012的解决方案,但实际上,由于VS2010和VS2013存在相同问题,这个工具也可能适用于这些版本。"VSCopyToWord"标签进一步确认了这是与Visual Studio复制到Word相关...

    sogoupinyin_2.3.1.0112_amd64.deb

    对于那些在Ubuntu 18.04上需要中文输入的用户,这个版本的搜狗拼音输入法提供了一种可靠的解决方案,能够帮助他们流畅地输入中文,而无需担心显示异常。同时,使用.deb包管理方式也确保了安装过程的简便性和系统的...

    _基于PHP Dreamweaver的动态网站开发中常见问题的探讨.pdf

    然而,在实际开发过程中,会遇到一些常见问题,本文将针对这些问题进行详细探讨。 1. **站点创建问题**: 创建PHP动态网站时,首先需要设置站点。在Dreamweaver中,应避免使用中文命名站点,并确保站点保存在...

Global site tag (gtag.js) - Google Analytics