java new String getBytes 到底怎么转换字符集的问题

我们常常遇到字符集转换的问题。

我要说的当然不是网站中遇到的ISO8859-1的那个傻BUG。

实例:

目标,把一个UTF-8的中文字符串转化成GBK的字符串。

新建一个GBK的java项目。

也就是说*.java文件中的字符是用GBK字符集保存的。

在main中,建一个中文字符串,那么这个静态串就是GBK字符。

再把它的属性,字符集改成UTF-8后,变成这样了。

 

然后,我们再建一个UTF-8的java项目。

在main中写入以下:

String str = "新建文本文档.txt";
  System.out.println(str);
  byte[] bs = null;
  try {
   bs = str.getBytes("UTF-8");
  } catch (UnsupportedEncodingException e1) {
   e1.printStackTrace();
  }
  System.out.print( "UTF-8: \n");
  for(int i=0;i<bs.length;i++){
   System.out.print( bs[i] + " ");
  }
  System.out.println();
  try {
   String tempStr ="";

   bs = str.getBytes("GBK");
   System.out.print( "GBK: \n");
   for(int i=0;i<bs.length;i++){
    System.out.print( bs[i] + " ");
   }
   System.out.println();
   System.out.println();

   tempStr = new String(bs,"GBK");
   System.out.println( "用UTF-8打印,这个GBK串(通过GBK重组后的): "+ tempStr );

   tempStr = new String(bs,"UTF-8");
   System.out.println( "用UTF-8打印,这个GBK串(通过UTF-8重组后的): "+ tempStr );

   System.out.print( "再把这个串"+tempStr+"转成UTF-8数组打印: \n");
   bs = tempStr.getBytes("UTF-8");
   for(int i=0;i<bs.length;i++){
    System.out.print( bs[i] + " ");
   }
   System.out.println();


  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }

 

得到的输入:

很明显,通过GBK重组后的字符串,打印出来的是明文,与我们原选做的测试完全不一样。

也就是说他根本没有被转码。

而通过UTF-8重组后的字符串,打印出来的才与我们原先看到的测试是一样的。

这才是真正的转码成功了。

 

这是为什么呢?

JDK帮助的描述是这样的。

getBytes(Charset charset) 
使用给定的 charset 将此 String 编码到 byte 序列,并将结果存储到新的 byte 数组。

String(byte[] bytes, Charset charset) 
通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。

 

应该这样理解:

getBytes是真正的在转码。

而new String是把它用某种码来显示。

像上面的那串乱码,它正在已经是GBK码了,用GBK显示正常,用UTF-8显示是乱码。

但,现在我们是在UTF-8环境下,所以要用UTF-8存字符串,最后把这个串输出给读它的平台。

你可以用,Xshell 的两种字符集环境来打印以上的输出。

在GBK连接的方式中,那串乱码被正常显示出来。

 

你感兴趣,还可以把这个例子反过来做一下,看是不是你想要的结果。

 

同时,我们再来理解一下tomcat中为什么要做这样一件事:

new String(str.getBytes("ISO-8859-1"),"gb2312"); 

这是因为,默认情况下,tomcat使用的是iso8859-1的编码方式传递。

而网页中设定的比如是gb2312或utf-8。这样得到的就是错的。

所以用ISO-8859-1得到字节流,再用gb2312来重组字节流得到gb2312的字符串流。

 

解决办法:

修改tomcat下的conf/server.xml文件
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改为: 
<Connector port="8080" useBodyEncodingForURI="true" URIEncoding="UTF-8" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

你可能感兴趣的:(java,转换,字符集)