分享
 
 
 

深入剖析Java编程中的中文问题及建议最优解决方法---下篇

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

深入剖析Java编程中的中文问题及建议最优解决方法--下篇

4、中文问题的分类及其建议最优解决办法

了解以上JAVA处理文件的原理之后,我们就可以提出了一套建议最优的解决汉字问题的办法。

我们的目标是:我们在中文系统中编辑的含有中文字符串或进行中文处理的JAVA源程序经编译后可以移值到任何其它的操作系统中正确运行,或拿到其它操作系统中编译后能正确运行,能正确地传递中文和英文参数,能正确地和数据库交流中英文字符串。

我们的具体思路是:在JAVA程序转码的入口和出口及JAVA程序同用户有输入输出转换的地方限制编码方法使之正确即可。

具体解决办法如下:

1、 针对直接在console上运行的类

对于这种情况,我们建议在程序编写时,如果需要从用户端接收用户的可能含有中文的输入或含有中文的输出,程序中应该采用字符流来处理输入和输出,具体来说,应用以下面向字符型节点流类型:

对文件:FileReader,FileWrieter

其字节型节点流类型为:FileInputStream,FileOutputStream

对内存(数组):CharArrayReader,CharArrayWriter

其字节型节点流类型为:ByteArrayInputStream,ByteArrayOutputStream

对内存(字符串):StringReader,StringWriter

对管道:PipedReader,PipedWriter

其字节型节点流类型为:PipedInputStream,PipedOutputStream

同时,应该用以下面向字符型处理流来处理输入和输出:

BufferedWriter,BufferedReader

其字节型的处理流为:BufferedInputeStream,BufferedOutputStream

InputStreamReader,OutputStreamWriter

其字节型的处理流为:DataInputStream,DataOutputStream

其中InputStreamReader和InputStreamWriter用于将字节流按照指定的字符编码集转换到字符流,如:

InputStreamReader in = new InputStreamReader(System.in,"GB2312");

OutputStreamWriter out = new OutputStreamWriter (System.out,"GB2312");

例如:采用如下的示例JAVA编码就达到了要求:

//Read.java

import java.io.*;

public class Read {

public static void main(String[] args) throws IOException {

String str = "\n中文测试,这是内部硬编码的串"+"\ntest english character";

String strin= "";

BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //设置输入接口按中文编码

BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //设置输出接口按中文编码

stdout.write("请输入:");

stdout.flush();

strin = stdin.readLine();

stdout.write("这是从用户输入的串:"+strin);

stdout.write(str);

stdout.flush();

}}

同时,在编译程序时,我们用以下方式来进行:

javac -encoding gb2312 Read.java

其运行结果如图5所示:

图5

2、 针对EJB类和不可以直接运行的支持类(如JavaBean类)

由于这种类它们本身被其它的类调用,不直接与用户交互,故对这种类来说,我们的建议的处理方式是内部程序中应该采用字符流来处理程序内部的中文字符串(具体如上面一节中一样),同时,在编译类时用-encoding gb2312参数指示源文件是中文格式编码的即可。

3、 针对Servlet类

针对Servlet,我们建议用以下方法:

在编译Servlet类的源程序时,用-encoding指定编码为GBK或GB2312,且在向用户输出时的编码部分用response对象的setContentType("text/html;charset=GBK");或gb2312来设置输出编码格式,同样在接收用户输入时,我们用request.setCharacterEncoding("GB2312");这样无论我们的servlet类移植到什么操作系统中,只有客户端的浏览器支持中文显示,就可以正确显示。如下是一个正确的示例:

//HelloWorld.java

package hello;

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class HelloWorld extends HttpServlet

{

public void init() throws ServletException { }

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

{

request.setCharacterEncoding("GB2312"); //设置输入编码格式

response.setContentType("text/html;charset=GB2312"); //设置输出编码格式

PrintWriter out = response.getWriter(); //建议使用PrintWriter输出

out.println("<hr>");

out.println("Hello World! This is created by Servlet!测试中文!");

out.println("<hr>");

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException

{

request.setCharacterEncoding("GB2312"); //设置输入编码格式

response.setContentType("text/html;charset=GB2312"); //设置输出编码格式

String name = request.getParameter("name");

String id = request.getParameter("id");

if(name==null) name="";

if(id==null) id="";

PrintWriter out = response.getWriter(); //建议使用PrintWriter输出

out.println("<hr>");

out.println("你传入的中文字串是:" + name);

out.println("<hr>你输入的id是:" + id);

out.println("<hr>");

}

public void destroy() { }

}

请用javac -encoding gb2312 HelloWorld.java来编译此程序。

测试此Servlet的程序如下所示:

<%@page contentType="text/html; charset=gb2312"%>

<%request.setCharacterEncoding("GB2312");%>

<html><head><title></title>

<Script language="JavaScript">

function Submit() {

//通过URL传递中文字符串值给Servlet

document.base.action = "./HelloWorld?name=中文";

document.base.method = "POST";

document.base.submit();

}

</Script>

</head>

<body bgcolor="#FFFFFF" text="#000000" topmargin="5">

<form name="base" method = "POST" target="_self">

<input name="id" type="text" value="" size="30">

<a href = "JavaScript:Submit()">传给Servlet</a>

</form></body></html>

其运行结果如图6所示:

图6

4、 JAVA程序和数据库之间

为避免JAVA程序和数据库之间数据传递出现乱码现象,我们建议采用以下最优方法来处理:

1、 对于JAVA程序的处理方法按我们指定的方法处理。

2、 把数据库默认支持的编码格式改为GBK或GB2312的。

如:在mysql中,我们可以在配置文件my.ini中加入以下语句实现:

在[mysqld]区增加:

default-character-set=gbk

并增加:

[client]

default-character-set=gbk

在SQL Server2K中,我们可以将数据库默认的语言设置为Simplified Chinese来达到目的。

5、 针对JSP代码

由于JSP是在运行时,由WEB容器进行动态编译的,如果我们没有指定JSP源文件的编码格式,则JSP编译器会获得服务器操作系统的file.encoding值来对JSP文件编译的,它在移植时最容易出问题,如在中文win2k中可以很好运行的jsp文件拿到英文linux中就不行,尽管客户端都是一样的,那是因为容器在编译JSP文件时获取的操作系统的编码不同造成的(在中文wink中的file.encoding和在英文Linux中file.encoding是不同的,且英文Linux的file.encoding对中文不支持,所以编译出来的JSP类就会有问题)。网络上讨论的大多数是此类问题,多是因为JSP文件移植平台时不能正确显示的问题,对于这类问题,我们了解了JAVA中程序编码转换的原理,解决起来就容易多了。我们建议的解决办法如下:

1、我们要保证JSP向客户端输出时是采用中文编码方式输出的,即无论如何我们首先在我们的JSP源代编中加入以下一行:

<%@page contentType="text/html; charset=gb2312"%>

2、为了让JSP能正确获得传入的参数,我们在JSP源文件头加入下面一句:

<%request.setCharacterEncoding("GB2312");%>

3、为了让JSP编译器能正确地解码我们的含有中文字符的JSP文件,我们需要在JSP源文件中指定我们的JSP源文件的编码格式,具体来说,我们在JSP源文件头上加入下面的一句即可:

<%@page pageEncoding="GB2312"%>或<%@page pageEncoding="GBK"%>

这是JSP规范2.0新增加的指令。

我们建议使用此方法来解JSP文件中的中文问题,下面的代码是一个正确做法的JSP文件的测试程序:

//testchinese.jsp

<%@page pageEncoding="GB2312"%>

<%@page contentType="text/html; charset=gb2312"%>

<%request.setCharacterEncoding("GB2312");%>

<%

String action = request.getParameter("ACTION");

String name = "";

String str = "";

if(action!=null && action.equals("SENT"))

{

name = request.getParameter("name");

str = request.getParameter("str");

}

%>

<html>

<head>

<title></title>

<Script language="JavaScript">

function Submit()

{

document.base.action = "?ACTION=SENT&str=传入的中文";

document.base.method = "POST";

document.base.submit();

}

</Script>

</head>

<body bgcolor="#FFFFFF" text="#000000" topmargin="5">

<form name="base" method = "POST" target="_self">

<input type="text" name="name" value="" size="30">

<a href = "JavaScript:Submit()">提交</a>

</form>

<%

if(action!=null && action.equals("SENT"))

{

out.println("<br>你输入的字符为:"+name);

out.println("<br>你通过URL传入的字符为:"+str);

}

%>

</body>

</html>

如图7是此程序运行的结果示意图:

图7

5、总结

在上面的详细分析中,我们清晰地给出了JAVA在处理源程序过程中的详细转换过程,为我们正确解决JAVA编程中的中文问题提供了基础。同时,我们给出了认为是最优的解决JAVA中文问题的办法。

6、参考资料

1、段明辉.Java 编程技术中汉字问题的分析及解决.

http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml

2、 周竞涛.关于Java中文问题的几条分析原则

http://www-900.ibm.com/developerWorks/cn/java/l-javachinese/index.shtml

7、作者介绍

作者:abnerchai,高级程序员,作者联系方法:josserchai@yahoo.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有