您的位置:首页 > 编程语言 > Java开发

【转】Java编码原理与解决方案

2009-12-02 17:47 435 查看
http://www.cn-java.com/www1/?uid-560221-action-viewspace-itemid-8390

一、Java编码是怎么回事?

对于使用中文以及其他非拉丁语系语言的开发人员来说,经常会遇到字符集编码问题。对于Java语言来说,在其内部使用的是UCS2编码(2个字节的Unicode编码)。这种编码并不属于某个语系的语言编码,它实际上是一种编码格式的世界语。在这个世界上所有可以在计算机中使用的语言都有对应的UCS2编码。

正是因为Java采用了UCS2,因此,在Java中可以使用世界上任何国家的语言来为变量名、方法名、类起名,如下面代码如下:

class 中国 {     public String 雄起()     {          return "中国雄起";     } }  中国 祖国 = new 中国(); System.out.println(祖国.雄起());
class 中国
{
public String 雄起()
{
return "中国雄起";
}
}

中国 祖国 = new 中国();
System.out.println(祖国.雄起());

哈哈,是不是有点象“中文编程”。实际上,也可以使用其他的语言来编程,如下面用韩文和日文来定义个类:


class 수퍼맨 {     public void スーパーマン() {  } }
class 수퍼맨
{
public void スーパーマン() { }
}

实际上,由于Java内部使用的是UCS2编码格式,因为,Java并不关心所使用的是哪种语言,而只要这种语言在UCS2中有定义就可以。

在UCS2编码中为不同国家的语言进行了分页,这个分页也叫“代码页”或“编码页”。中文根据包含中文字符的多少,分了很多代码页,如cp935、cp936等,然而,这些都是在UCS2中的代码页名,而对于操作系统来说,如微软的windows,一开始的中文编码为GB2312,后来扩展成了GBK。其实GBK和cp936是完全等效的,用它们哪个都行。

二、Java编码转换

上面说了这么多,在这一部分我们做一些编码转换,看看会发生什么事情。

先定义一个字符串变量:

String gbk = "中国"; // “中国”在Java内部是以UCS2格式保存的

用下面的语言输出一定会输出中文:

System.out.println(gbk);

实现上,当我们从IDE输入“中国”时,用的是java源代码文件保存的格式,一般是GBK,有时也可是utf-8,而在Java编译程序时,会不由分说地将所有的编码格式转换成utf-8编码,读者可以用UltraEdit或其他的二进制编辑器打开上面的“中国.class”,看看所生成的二进制是否有utf-8的编码(utf-8和ucs2之间的转换非常容易,因为utf-8和ucs2之间是用公式进行转换的,而不是到代码页去查,这就相当于将二进制转成16进制一样,4个字节一组)。如“中国”的utf-8编码按着GBK解析就是“涓 浗”。如下图所示。

代码 package servlet;

io.IOException;
io.PrintWriter;
servlet.ServletException;
servlet.http.HttpServlet;
servlet.http.HttpServletRequest;
servlet.http.HttpServletResponse;

public class MyPost extends HttpServlet
{

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
getParameter("user");
out.println(user);
}
}

package servlet;    import java.io.IOException;   import java.io.PrintWriter;   import javax.servlet.ServletException;   import javax.servlet.http.HttpServlet;   import javax.servlet.http.HttpServletRequest;   import javax.servlet.http.HttpServletResponse;    public class MyPost extends HttpServlet   {        public void doPost(HttpServletRequest request, HttpServletResponse response)               throws ServletException, IOException       {           String user = request.getParameter("user");           System.out.println(user);       }   }
如果中main.jsp中输入中文后,向MyPost提交,在控制台中会输出“中国”,一看就是乱码。如果将IE的当前编码设成其他的,如由utf-8改为gbk,仍然会出现乱码,只是乱得不一样而已。这是因为客户端提交数据时是根据浏览器当前的编码格式来提交的,如浏览器当前为gbk编码,就以gbk编码格式来提交。 这本身是不会出现乱码的,问题就出在Web服务器接收数据的时候,HttpServletRequest在将客户端传来的数据转成ucs2码上出了问题。在默认情况下,是按着iso-8859-1编码格式来转的,而这种编码格式并不支持中文,所以也就无法正常显示中文了,解决这个问题的方法是用和客户端浏览器当前编码格式一致的编码来转换,如果是utf-8,则在doPost方法中应该用以下的语句来处理:

request.setCharacterEncoding("utf-8");

为了对每一个Servlet都起作用,可以将上面的语句加到filter里。

另外,我们一般使用象MyEclipse一样的IDE来编写jsp文件,这样的工具会根据pageEncoding属性将jsp文件保存成相应的编码格式,但如果要使用象记事本一样的简单的编辑器来编写jsp文件,如果pageEncoding是utf-8,而在默认时,记事本会将文件保存成iso-8859-1(ascii)格式,但在myeclipse里,如果文件中有中文,它是不允许我们保存成不支持中文的编码格式的,但记事本并不认识jsp,因此,这时在ie中就无法正确显示出中文了。除非用记事本将其保存在utf-8格式。如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: