再次,对于放在操作系统中的.Java源程序文件,在编译时,我们可以指定它内容的编码格式,具体来说用-encoding来指定。注意:如果源程序中含有中文字符,而你用-encoding指定为其它的编码字符,显然是要出错的。 用-encoding指定源文件的编码方式为GBK或gb2312,无论我们在什么系统上编译含有中文字符的Java源程序都不会有问题,它都会正确地将中文转化为UNICODE存储在class文件中。 然后,我们必须清楚,几乎所有的WEB容器在其内部默认的字符编码格式都是以ISO-8859-1为默认值的,同时,几乎所有的浏览器在传递参数时都是默认以UTF-8的方式来传递参数的。 所以,虽然我们的Java源文件在出入口的地方指定了正确的编码方式,但其在容器内部运行时还是以ISO-8859-1来处理的。 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 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() { } } |