public static String change(String str)
    {
        try
        {
            if(str != null)
                str = new String(str.getBytes("GB2312"), "ISO-8859-1");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return str;
}
这个里面的str.getBytes("GB2312")和"ISO-8859-1"是把什么转换成什么

解决方案 »

  1.   

    这个最简单的办法就是去查API你的程序的意思是。。先用GB2312的编码规则把字符串打散成字节数组,然后再用ISO-8859-1编码规则进行重新编码懂了吗?
      

  2.   

    new String(, "ISO-8859-1")是创建一个ISO-8859-1编码的字符串str.getBytes("GB2312")是得到str的字节数组,以给定参数进行编码
      

  3.   

    也就是说这个里面的str = new String(str.getBytes("GB2312"), "ISO-8859-1");
    str.getBytes("GB2312"), 的“GB2312”可以随便写吗?
      

  4.   

    这个做很多java开发多年的都不一定知道,有些也只是有那么个概念,其实java中的编码也是比较容易搞错的一个地方,我把我的一些研究发出来吧,希望对你有帮助,可以从根本上解答这个问题。
    --------------------------------------------------------------------------
    在java中的编码大家一直可能有个误区,对编码概念的理解也一直比较模糊,那java他是怎样的一个编码
    规则呢,其实如果深入的研究很容易的知道其编码过程。外部的文本或有编码的信息进入java要被java理解和处理的话,必须转变成utf-16,不管输入的是gbk
    还是其它的国家的编码信息要想被java认识和处理(除非不作处理,直接当作一个黑盒子传递)就必须
    得把gbk或其它国家的编码方式转换成utf-16的编码,才能被java查找和显示(System.out.println(str))
    等。  当java中要输出信息时也要还原或者指定编码,告诉java请把你的utf-16转成我要的utf-8的型式。
      就像字节转成字符串一样。new String(byte[] b,String charsetName)就是表示把指定的
      charsetName编码转成utf-16(java系统使用的中间编码)
      
      因为如:一个字符串为gbk格式,后来被当作utf-8读取当然会乱码,我们可以先把乱码的字符先
      utf-8的方式把utf-16的字符转成字节,然后再以gbk的方式转成utf-16
      
      有一点我们要注意,在这些转换过程中我们都是从其它编码转成utf-16,或从utf-16转成其它编码
      因此utf-16是java使用的中间编码方式。16。在字符串转字节时,编码是怎样的?默认编码是怎样的。
    -------------------------------------------------------------------------------------------------
     测试代码如下:
     String str = "ab12,n中";
    byte[] bt;
    try {
    bt = str.getBytes("gb2312");
    System.out.println(bt.length);
    for(int i=0;i<bt.length;i++)
    {
    Byte b = (Byte)bt[i];
    System.out.println(b.longValue());
    }
    } catch (UnsupportedEncodingException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    }

    String str = "ab12,n中";
    byte[] bt= str.getBytes();
    System.out.println(bt.length);
    for(int i=0;i<bt.length;i++)
    {
    Byte b = (Byte)bt[i];
    System.out.println(b.longValue());
    }
    输出结果都为:
    8
    97
    98
    49
    50
    44
    110
    -42
    -48
    注:在测试中我们看gb2312的中字编码为:D6 D0
    D6 = 214  256-42=214 
    如此说明,这里的字符默认编码使用系统的编码,也就当前系统的编码方式。我用的是简体操作系统
    当然是简体编码
      

  5.   

    以下是我的别一个研究分析,也发出来给给大家看看。
    ------------------------------------------------------------
    测时,我在客户用gb2312进行提交,服务器接收时显示是乱码。TestForm fo = (TestForm) form;
    String myName = fo.getMyName();//request.getParameter("myName");
    System.out.println(myName);
    myName = Pcode.toCode(myName,"8859_1","gb2312");
    if(myName!=null)
    {
    System.out.println(myName);
    byte[] b = myName.getBytes();
    for(int i=0;i<b.length;i++)
    {
    System.out.println(b[i]);
    }
    }
    return mapping.findForward("show");

    从客户接收的myName如果为中文的化,显示为乱码,如果经过。
    myName = Pcode.toCode(myName,"8859_1","gb2312");转换后正常了,
    从而可见myName的确接收的是错误编码后在字符串,我们得用Pcode先转回去
    再转回来。

    这里说明几个问题。
    1)默认的情况下(这里测试环境为tomcat6.0)服务器接收时的使用编码为8859_1
    除非我们指定request的编码,同时编码必须和客户一致。
    2)我们看到打印出来?号,如果直接输出降byte的话为63,也就是说乱码的字输出
    来为?号或乱码,这是在客户转过来就乱了,还是System.out.println时乱的呢。
    其实是System.out.println时乱的,println对于大于ASCII的值,但又不能显示为
    中文的字显示为?号。因此并非没有转给过来,而是打印信息时出现问题。

    而myName.getBytes();中的默认编码为当前系统的编码,也就是说,在把字符串
    转在byte时,是把utf-16转成了gbk的字节。

    测试:
    -----------------------------------------------------------------------------------------------------------------
    public static void main(String[] args) {
    String str = "中国";
    try {
    byte[] b = str.getBytes("GBK"); //UTF16->GBK
    print(b);
    str = new String(b,"8859_1"); //8859_1->UTF16
    System.out.println("----"+str);
    byte[] bb = str.getBytes("GBK"); //UTF16->GBK
    print(bb);
    str = new String(bb,"GBK"); //GBK->UTF16
    System.out.println("----"+str.length());
    byte[] bc = str.getBytes("8859_1"); //UTF16->8859_1
    print(bc);
    str = new String(bc,"GBK"); //GBK->UTF16
    System.out.println("----"+str.length());
    System.out.println(str);
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    }

    public static void print(byte[] b)
    {
    for(int i=0;i<b.length;i++)
    {
    System.out.println(b[i]);
    }
    System.out.println("------------------------");
    }


    输出结果:
    ----------------------------------------------------------------------------------------------------------------------
    -42
    -48
    -71
    -6
    ------------------------ //第一次输出时正常。对应于byte[] b = str.getBytes("GBK"); 
    ----???ú //在转换时出现问题,str = new String(b,"8859_1"); 前三个字节数字过大,超出ascii的表示范围,只有最后一个-6被表示为ú
    63
    63
    63
    -88
    -78
    ------------------------
    ----4
    63
    63
    63
    -6
    ------------------------
    ----4
    ????

    注:那这里真正的乱码(也就是不可还原)到底是那一个环节呢,在测试中发现,把
    1)byte[] b = str.getBytes("GBK"); 
    2)str = new String(b,"8859_1"); 
    3)byte[] bb = str.getBytes("GBK");
    这里问题出现在第三行代码,测试中发现第二行代执行后还是可以还原的。
    因此测试的结果很显然是再转成GBK出现错误。其实字符串也是char[]数组,而char对于java来说,
    就是用两个数字表示的,也就是utf-16.


    从上面我们可以得出,中国两个字的编码为:d6d0 b9fa  
    在经过str = new String(b,"8859_1"); 后应为:d600 d000 b900 fa00 
    因为8859_1会把一个字节当一个ascii进行处理,所以表示为UTF-16时用了8个字节。也就是说相当于
    表示了4个字。(UTF-16用两个字节表示一个字),如果按原来的编码还原的话,当然不会有问题。
    只是重新把d600变成一个字节不行了。d6,但如果我们用GBK来进行转换的话,因为gbk也是用两个
    字节来表示的,因此在转成字节后应为00d6 00d0 00b9 00fa,理论上字节数组会增长,从原来的4
    变成8,但是为什么不是这样呢。很显然是byte[] bb = str.getBytes("GBK");的原因
    这条语句如果碰到不是GBK字符的字就会用?号代替。

    00fa确实为字符ú ,不过在字库中查找00d6也是有字符的,不知为什么是问号。