漂洋过海

漂洋过海
数据加载中……
java 的字符编码问题

java 的字符编码问题-2  

2008-11-17 11:01:23|  分类: JSP,JAVA,C等相关 |  标签: |字号 订阅

二、JAVA 对字符的处理
    1. getBytes(charset)
       
        这是 java 字符串处理的一个标准函数,其作用是将字符串所表示的字符按照 charset 编码,并以字节方式表示。注意字符串在 java 内存中总是按 unicode 编码存储的。
    Java程序从输入流、文件或字符文字量等途径获得字符串时,均会做字符编码的转换,例如InputStreamReader 的构造函数中就需要指定编码方式,而对于从文件和字符文字量中获得字符串时,均采用系统默认的编码方式对字符数据进行解码。考虑下面一段代码:

String str=””;

byte[] bytes = str.getBytes();

bytes = str.getBytes(“ISO-8859-1”);

语句①:将一个只含有一个字符的字符串文字量赋给 String 类的一个对象 str,字符文字量是按照操作系统默认编码方式进行编码,在中文 windows 系统中通常是“GBK”,“中”在GBK编码中是0xD6D0,在将该字符赋给str时,Java会对该字符串进行编码转换,即将GBK编码方式的“中”转换成Unicode编码方式的“中”,Unicode编码方式“中”的编码是0x4E2D,所以str在程序运行期间在内存中的二进制表示成16进制就是0x4E2D

语句②:获得str字符串的二进制形式。getBytes(String encoding)方法需要指定编码方式,表示获得该字符串在何种编码方式中的二进制形式。此语句中没有设置参数,表示采用操作系统默认的编码方式,即此处获得的bytesGBK编码中的二进制形式,即bytes[0]=0xD6, bytes[1]=0xD0

语句③:该语句与语句②的区别就是指定了编码方式,此处指定的是ISO-8859-1,即通常所说的Latin-1,该编码采用8bit对字符编码,所以编码空间中只有256个字符。该编码中只包含了基本的ASCII码和一些扩展的其它西欧字符,所以该字符集中不可能包含中文的“中”字,也就是说Java虚拟机无法在ISO-8859-1编码集中找到“中”字对应的编码,针对这种情况,就只返回一个问号(?,0x3f)字符,所以此时bytes.length只有1,且bytes[0]=0x3f

2.new String(byte[] bytes, String encoding)

getBytes()方法从字符串获得二进制的字节数组。如果要从二进制的字节数组获得字符串,则就需要使用new String(byte[] bytes, String encoding)方法,该方法按照encoding编码方法对字节数组bytes中的二进制数组进行解析,生成一个新的字符串对象。

byte[] bytes = {(byte)0xD6, (byte)0xD0, (byte)0x31};

String str = new String(bytes);

str = new String(bytes,”ISO-8859-1”);

 

语句①:定义一个字节数组。

语句②:将该字节数组中的二进制数据按照默认的编码方式(GBK)编码成字符串,我们知道GBK0xD6 0xD0表示“中”,0x31表示字符“1”(GBK兼容ASCII,但不兼容ISO-8859-1ASCII之外的部分),所以str得到的值是“中1”。

语句③:该句用ISO-8859-1编码方式对该字节数据进行编码,由于在ISO-8859-1编码方式中一个字节会被解析成一个字符,所以该字节数组会被解释成包含三个字符的字符串,但由于在ISO-8859-1编码方式中没有对应0xD60xD0的字符,所以前两个字符会产生两个问号,由于0x31ISO-8859-1编码中对应字符“1”(ISO-8859-1也兼容ASCII),所以此语句得到str的值是“??1”。

3.setCharacterEncoding()

该函数用来设置http请求或者相应的编码。

对于request,是指提交内容的编码,指定后可以通过getParameter()直接获得正确的字符串,如果不指定,则默认使用iso8859-1 编码,需要进一步处理。值得注意的是在执行setCharacterEncoding()之前,不能执行任何 getParameter()而且,该指定只对POST方法有效,对GET方法无效。分析原因,应该是在执行第一个getParameter()的时候,java将会按照编码分析所有的提交内容,而后续的getParameter()不再进行分析,所以setCharacterEncoding()无效。而对于GET方法提交表单时,提交的内容在URL中,一开始就已经按照编码分析所有的提交内容,setCharacterEncoding()自然就无效。

对于response,则是指定输出内容的编码,同时,该设置会传递给浏览器,告诉浏览器输出内容所采用的编码。

三、页面编码
    页面编码主要有两方面,一是页面本身的编码格式,即以什么编码方式保存,二是客户端浏览器以什么编码格式显示页面。
    1. 页面保存编码格式
    1). HTML 页面的编码要看你保存文件时的编码选项,多数的网页编辑软件可以让你选择编码的类型,默认为本地编码,为了使网页减少编码的问题,最好保存为 UTF-8 编码格式。
     2). JSP 页面使用下列标签指定 JSP 源文件的编码格式,具体来说,我们在JSP源文件头上加入下面的一句即可:
    <%@page pageEncoding="xxx"%>xxx可以为GB2312GBKUTF-8(和MySQL不同,MySQL UTF8)等等,其默认值为ISO-8859-1。保存文件时的编码应该与xxx 一致。
    2. 页面显示编码(通知客户端浏览器用什么字符集编码显示页面)
   
    使用 <META http-equiv="content-type" content="text/html; charset=xxx"> 标签设置页面显示编码
    使用 response.setContentType("text/html; charset=xxx");来指定生成的页面编码。
   

使用 <%@ page language="java" contentType="text/html; charset=xxx"%> 设置页面显示编码。字符集的默认值为ISO-8859-1

3. 页面输入编码

在设置页面显示编码的同时,指定了页面的输入方式。如果没有指定页面编码,则使用操作系统本身的默认编码。

四、表单传递参数编码

使用表单输入数据时,处理过程如下:

User input   *(gbk:d6d0 cec4)  

browser   *(gbk: d6d0 cec4)  

web server   iso8859-1(00d6 00d 000ce 00c4)   class,需要在class中进行处理:getbytes("iso8859-1")d6 d0 ce c4new String("gbk")d6d0 cec4,内存中以 unicode编码则为4e2d 6587

1.用户输入的编码方式和页面指定的编码有关。

2.从 browser web server可以在表单中指定提交内容时使用的字符集,否则会使用页面指定的编码。而如果在url中直接用 ? 的方式输入参数,则其编码往往是操作系统本身的编码,因为这时和页面无关。

3 Web server接收到的是字节流,默认时(getParameter)会以 iso8859-1编码处理之,结果是不正确的,所以需要进行处理。但如果预先设置了编码(通过 request. setCharacterEncoding ()),则能够直接获取到正确的结果。

posted on 2012-08-13 12:23 漂洋过海 阅读(99) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: