您的位置:首页 > 其它

测试我的BLOG on CSDN

2005-04-09 16:03 429 查看
解决[/b]java[/b]中文问题[/b]
[/b]导言... 1
环境... 1
解决之道... 1
一. jsp中文显示... 1
1. 往地址栏直接输入中文名... 1
2. 通过超级连接传输... 2
3. 通过ActionForm传输... 2
4. Web服务器URIEncoding. 2
5. Js里传参数... 2
二. 数据库中文... 3
三. 邮件中文... 3
1. 发中文名附件... 3
2. 收中文名附件... 3
四. soap消息中文... 5
1. Base64编码... 5
2. Unicode编码... 5
五. 浏览器显示中文名文件... 5
六. 上传中文名文件... 6
七. 多语言混显问题... 6
参考资料... 7

[/b]

导言

编写java方面的应用程序难点之一就是中文如何解决。本文就这个问题作了一些探讨。

环境

解决之道

一.jsp中文显示

1. 往地址栏直接输入中文名

如:输入http://localhost:8888/UUM/tree.do?type=ou&dn=ou=测试公司,dc=cmhk,dc=com String dn=request.getParameter("dn"); dn=new String(dn.getBytes("ISO-8859-1"));//显示中文

2. 通过超级连接传输

如:<a href="tree.do?type=ou&dn=ou=测试公司,dc=cmhk,dc=com">test</a> String dn=request.getParameter("dn"); dn=new String(dn.getBytes("ISO-8859-1"),"UTF-8"));

3. 通过ActionForm传输

<html:form action=””> <html:text property=”dn”> </html:form> 选择一:使用编码过滤器转换成中文选择二:编码转换 String dn = form.getDn(); dn = new String(dn.getBytes("ISO-8859-1"),"UTF-8"));

4. Web服务器URIEncoding

默认为ISO-8859-1,有必要时可以修改。参见浏览器显示中文名文件

5. Js里传参数

比如: var str=""; if(document.ws.dns.value!=""){ str = document.ws.dns.value+"@"+document.ws.names.value; } var rt=window.showModalDialog( "cmhk/portal/ldapFrame.jsp?type=dep&dn=ou=测试公司,dc=cmhk,dc=com", str, "dialogWidth=800px;dialogHeight=600px"); if(rt!=null&&rt!=""){ var ss = rt.split("@"); document.ws.dns.value=ss[0]; document.ws.names.value=ss[1]; document.ws.to.value=ss[1]; }在ldapFrame.jsp里就要作如下转换,才能得到正确的中文(与一.1类似) String dn = new String(request.getParameter("dn").getBytes("ISO-8859-1"));

二.数据库中文

数据库字符编码与传入的数据编码保持一致就可以了。

三.邮件中文

1. 发中文名附件

@messageBodyPart.setFileName(MimeUtility.encodeWord(fileName));

@MimeBodyPart.setFileName(new String(file.getName().getBytes(), "ISO8859-1"));

@JavaMail能很好的支持中文,但在测试过程中发现使用JavaMail发带有中文文件名的
附件时,文件名是乱码,经测试与查看源文件发现,是在JavaMail包里的一个写邮件
的方法没有考虑国际化因素,对双字节或多字节的字符没有考虑。即在
com.sun.mail.util.LineOutputStream调用
com.sun.mail.util.ASCIIUtility.getBytes(String s);
此方法直接将字符串转化成字符然后转换成字节。其实在String类里的getBytes()
方法就直接可以按照系统缺省的编码正确转换成字节码。
解决方法:将com.sun.mail.util.LineOutputStream中调用ASCIIUtility.getBytes(String s);
方法的部分改为s.getBytes()解决了此问题。
用重新编译好的LineOutputStream.class文件替换javamail里的Com/sun/mail/util/LineOutputStream.class文件即可

2. 收中文名附件

现在研究javamail的人越来越多,现在我就谈谈在javamail中大家都会遇到的附件中文问题,由于sun的java的中文问题,导致当附件是中文时将出现乱码,导致程序异常,如何避免呢??我在学习javamail时采用如下方法首先对邮件体进行分析,首先判断邮件体是否有附件:
Object out_content = message[i].getContent();
if (!(out_content instanceof Multipart)){//不是复合邮件体,既是不带附件。
partname = new String[0];
return partname;
}
如果是复合邮件体,那么就可以调用如下的方法取得中文文件名:
public static String getISOFileName(Part body){
//设置一个标志,判断文件名从Content-Disposition中获取还是从Content-Type中获取
boolean flag=true;
if(body==null){
return null;
}
String[] cdis;
try{
cdis=body.getHeader("Content-Disposition");
}
catch(Exception e){
return null;
}
if(cdis==null){
flag=false;
}
if(!flag){
try{
cdis=body.getHeader("Content-Type");
}
catch(Exception e){
return null;
}
}
if(cdis==null){
return null;
}
if(cdis[0]==null){
return null;
}
//从Content-Disposition中获取文件名
if(flag){
int pos=cdis[0].indexOf("filename=");
if(pos<0){
return null;
}
//如果文件名带引号
if(cdis[0].charAt(cdis[0].length()-1)=='"'){
return cdis[0].substring(pos+10,cdis[0].length()-1);
}
return cdis[0].substring(pos+9,cdis[0].length());
}else{
int pos=cdis[0].indexOf("name=");
if(pos<0){
return null;
}
//如果文件名带引号
if(cdis[0].charAt(cdis[0].length()-1)=='"'){
return cdis[0].substring(pos+6,cdis[0].length()-1);
}
return cdis[0].substring(pos+5,cdis[0].length());
}
}
但是有一种情况下,取得的中文文件名也是乱码,原因有的邮件服务器在发送邮件时,对附件名进行了特殊的编码,解决如上问题的方法如下:
首先:
1)用如上的方法取得中文文件名:
String filename= new String(getISOFileName(part).getBytes("ISO-8859-1"),"gb2312");
然后创建文件,如果发生FileNotFoundException异常,说明取得的文件名是经过特殊编码的--我们取得到的未解码的,是乱吗,那么就要用javamail提供的函数decodeText进行解码。具体方法如下。
try{
myFileoutputstream= new FileOutputStream(filename);
}catch(FileNotFoundException fe){
try{
if (filepath.exists()){
filename = new File(filepath,MimeUtility.decodeText(getISOFileName(part)));
}catch(Exception e){
System.out.println("getpart(int i)重新生成文件:"+e.toString());
}
}catch(Exception e){
System.out.println("getpart(int i)重新生成文件:"+e.toString());
}
}
经过如上步骤,就能彻底解决javamail附件中文名乱码问题了。

四.soap消息中文

1. Base64编码

参见【CMHK-OA-SD-WEB服务.doc】

2. Unicode编码

参见【CMHK-OA-SD-WEB服务.doc】

五.浏览器显示中文名文件

在tomcat下,修改配置文件server.xml <!-- Define a non-SSL Coyote HTTP/1.1 Connector on port 8080 --> <Connector port="82" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/>URIEncoding="UTF-8"属性支持中文文件浏览例如:在地址栏输入Http://localhost:82/WS/某某.doc,就不会出现找不到该文件的情况(目录下有这个文件)。

六.上传中文名文件

使用javazoom的UploadBean上传组件,可以上传中文名文件MultipartFormDataRequest mrequest = new MultipartFormDataRequest( request, null, MultipartFormDataRequest.MAXCONTENTLENGTHALLOWED, MultipartFormDataRequest.COSPARSER, "UTF-8");//指定UTF-8编码

七.多语言混显问题

因为一直不信Java竟会有不能混排显示多国语言的BUG,这个周末研究了一下Servlet、
Jsp的多国语言显示的问题,也就是Servlet的多字符集问题,由于我对字符集的概念还
不是很清晰所以写出的东西未必是准确的,我是这样理解Java中的字符集的:在运行时
,每个字符串对象中存储的都是编码为UNICODE内码的(我觉得所有的语言中都是有相应
编码的,因为在计算机内部字符串总是用内码来表示的,只不过一般计算机语言中的字
符串编码时平台相关的,而Java则采用了平台无关的UNICODE)。

  Java从一个byte流中读取一个字符串时,将把平台相关的byte转变为平台无关的Un
icode字符串。在输出时Java将把Unicode字符串转变为平台相关的byte流,如果某个Un
icode字符在某个平台上不存在,将会输出一个'?'。举个例子:在中文Windows中,Jav
a读出一个"GB2312"编码的文件(可以是任何流)到内存中构造字符串对象,将会把GB2
312编码的文字转变为Unicode编码的字符串,如果把这个字符串输出又将会把Unicode字
符串转化为GB2312的byte流或数组:"中文测试"----->"/u4e2d/u6587/u6d4b/u8bd5"--
--->"中文测试"。

如下例程:
byte[] bytes = new byte[]{(byte)0xd6, (byte)0xd0, (byte)0xce, (byte)0xc4,
(byte)0xb2, (byte)0xe2, (byte)0xca, (byte)0xd4};//GBK编码的"中文测试"
java.io.ByteArrayInputStream bin = new java.io.ByteArrayInputStream(bytes);
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io. Inpu
tStreamReader (bin,"GBK"));
String msg = reader.readLine();

参考资料

u http://www.w3.org/TR/unicode-xml/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: