专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » 解决乱码:这是我们公司总结的一些关于中文乱码问题的一些解决方案和经验和大家分享! »正文

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

来源: 发布时间:星期四, 2009年2月12日 浏览:153次 评论:0


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

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

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 2进制:
1100010011100011
由于只有两位我们按照两位编码来排但是我们发现这行不通第7位不是0因此返回\"?\"
0x4f60 2进制:
0100111101100000
我们用utf-8补齐变成:
111001001011110110100000
e4--bd--a0
于是返回:0xe4,0xbd,0xa0

3.
其实核心是char,然而要把转化成必须经过编码.length其实就是char长度如果使用区别编码很可能会错分造成散字和乱码
例如:
Stringencoding=“”;
b={()\'\\u00c4\',()\'\\u00e3\'};


Stringstr=String(b,encoding);  
如果encoding=8859_1会有两个字但是encoding=gb2312只有个字这个问题在处理分页是经常发生

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

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

如果用gb2312编译你会找到e4bda0字段;
如果用8859_1编译00c400e3 2进制:
00000000110001000000000011100011
每个都大于7位因此用11位编码:
11000001100001001100001110100011
c1--84-- c3-- a3
你会找到c184c3a3

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

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

7.发生编码地方:
从数据库到java——〉char
从java到数据库char——〉
从文件到java——〉char
从java到文件char——〉
从java到页面显示char——〉
从页面form提交数据到java——〉char
从流到java——〉char
从java到流char——〉

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

<web-app>
<filter>
<filter-name>RequestFilter</filter-name>
<filter->net.golden.uirs.util.RequestFilter</filter->
<init-param>
<param-name>char</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.CharacterEncoding(this.filterConfig.getInitParameter(\"char\"));//设置集?
实际上是设置了——〉charencoding
try{
(userIdnull||userId.equals(\"\")){
(!request.getRequestURL.toString.matches(
\".*/uirs/logon/logon(Controller){0,1}\\\\x2Ejsp$\")){
session.invalidate;
response.sendRedirect(request.getContextPath+
\"/uirs/logon/logon.jsp\");
}
}
{//看看是否具有信息上报系统权限
(!net.golden.uirs.util.UirsChecker.check(userId,\"信息上报系统\",
net.golden.uirs.util.UirsChecker.ACTION_DO)){
(!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);
}





0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: