Java中的字符编码问题处理心得总结

 更新时间:2016年06月26日 15:18:02   作者:阿诺  
Java中的String类默认是Unicode编码,大家平常所说的UTF-8就是使用最广的一种unicode的实现方式,以下我们还是来看一下Java中的字符编码问题处理心得总结:

当面对一串字节流的时候,如果不指定它的编码,其实际意义是无法知道的。
这句话应该也是我们面对“字符转字节,字节转字符”问题时候时刻记在脑子里的。否则乱码问题可能就接踵而至。
其实乱码问题的本质就是Encoding和Decoding用的不是一个编码,明白了这个道理就很好解决乱码问题了。
Java中常见的时候有如下:
1. String类使用byte[]的构造函数 String(byte[] bytes),String类同时提供了两个重载
(1)String(byte[] bytes, Charset charset) 
(2)String(byte[] bytes, String charsetName) 就是用来指定编码的。

2. String类的getBytes函数 byte[] getBytes() 同样有如下两个重载:
(1)byte[] getBytes(Charset charset) 
(2) byte[] getBytes(String charsetName)
所有不需指定编码的都是使用the platform's default charset, 可使用System.getProperty("file.encoding"),Charset.defaultCharset()获的。
3. PrintStream的 print(String s)同样设计到这个问题,为此PrintStream的构造函数中除了PrintStream(File file) 还有PrintStream(File file, String csn)
否则the string's characters are converted into bytes according to the platform's default character encoding,
 DataOutputStream构造时没有方法指定编码,但其提供了一个writeUTF(String str)

举开头的例子说明指定编码的必要:
如果一个网页指定编码为utf-8, <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />, 页面上有一个form,提交到一个servlet
那么用户输入的字符传过来的字节流就是按指定编码encoding的,例如你输入了"Hello你好",如果是utf-8,那么传过来的就是如下:     

[104, 101, 108, 108, 111, -28, -67, -96, -27, -91, -67] 

, 我们看到后面汉字每个用了3个字节,这个可以参考Utf-8的相关知识。
但如果你页面指定的是GBK,那传过来的就不一样了:

 [104, 101, 108, 108, 111, -60, -29, -70, -61]

所以servlet端,当使用request.getParameter的时候内部应该是调用
String s = new String(bytes, response.getEncoding())的,如果你response没有设置编码,那么就采用默认的编码null会转为java 平台的GBK,那中文就变成乱码了。
所以为了避免乱码,jsp站点一般设一个过滤器,所有的页面、servet都设置统一的编码。response.setEncoding, request.setEncoding.

Java的String内部是一个char[], char是一个用16位存储的utf-16编码的单元。为此,当要把字符、字符串转为字节输出到文件、网络,或者从文件、网络读到的字节流还原为有实际意义的字符,都要明白其编码是什么。

2016626151159929.jpg (690×492)

几点心得
1.String类始终是以Unicode编码形式存储.
2.注意String.getBytes()的使用:
   如果不带字符集参数,就会依赖于JVM的字符集编码,LINUX上一般为UNICODE,WINDOWS下一般为GBK.(要想改变JVM缺省字符集编码,启动JVM时用选项-Dfile.encodeing=UTF-8.
  为了安全起见,建议始终带参数调用,例如:String s ; s.getBytes("UTF-8")。
3.Charset类非常好用,
(1)Charset.encode 是编码,即把String按你指定的字符集编码格式进行编码后输出字节数组。
(2)Charset.decode 是解码,即把一个字节数组按你指定的字符集编码格式进行解码后输出成字符串。

举例如下:   

 String s = Charset.defaultCharset().displayName();
  String s1 = "我喜欢你,My Love";
  
  ByteBuffer bb1 = ByteBuffer.wrap(s1.getBytes("UTF-8"));

  for(byte bt:bb1.array()){
    System.out.printf("%x",bt);
  }
  //char[]用法
  char[] chArray={'I','L','o','v','e','你'};

  //CharBuffer用法
  CharBuffer cb = CharBuffer.wrap(chArray);
  //重新定位指针
  cb.flip();

  String s2= new String(chArray);

  //ByteBuffer用法
  ByteBuffer bb2 = Charset.forName("utf-8").encode(cb);

  // 利用Charset编码为指定字符集

  ByteBuffer bb3 = Charset.forName("utf-8").encode(s1);

  byte [] b  = bb3.array() ;

  // 利用Charset按指定字符集解码为字符串
  ByteBuffer bb4= ByteBuffer.wrap(b);

  String s2 = Charset.forName("utf-8").decode(bb4).toString();

相关文章

  • Springboot整合hutool验证码的实例代码

    Springboot整合hutool验证码的实例代码

    在 Spring Boot 中,你可以将 Hutool 生成验证码的功能集成到 RESTful API 接口中,这篇文章主要介绍了Springboot整合hutool验证码,需要的朋友可以参考下
    2024-08-08
  • spring 和 idea 建议不要使用 @Autowired注解的原因解析

    spring 和 idea 建议不要使用 @Autowired注解的原因解析

    @Autowired 是Spring框架的注解,而@Resource是JavaEE的注解,这篇文章主要介绍了spring和idea建议不要使用@Autowired注解的相关知识,需要的朋友可以参考下
    2023-11-11
  • Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

    Nacos服务发现并发启动scheduleUpdate定时任务的流程分析

    这篇文章主要介绍了Nacos服务发现并发启动scheduleUpdate定时任务,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02
  • Java实现XML格式与JSON格式互相转换的方法

    Java实现XML格式与JSON格式互相转换的方法

    这篇文章主要介绍了Java实现XML格式与JSON格式互相转换的方法,方法通过实例代码给大家介绍的非常详细,选择使用哪种格式通常取决于项目的需求和上下文,所以格式转换就成了我们必备的技能,具体实现代码跟随小编一起看看吧
    2023-10-10
  • SpringBoot2.3.0配置JPA的实现示例

    SpringBoot2.3.0配置JPA的实现示例

    这篇文章主要介绍了SpringBoot2.3.0配置JPA的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • SpringBoot整合MongoDB全过程

    SpringBoot整合MongoDB全过程

    这篇文章主要介绍了SpringBoot整合MongoDB全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • java 中RSA的方式实现非对称加密的实例

    java 中RSA的方式实现非对称加密的实例

    这篇文章主要介绍了java 中RSA的方式实现非对称加密的实例的相关资料,这里提供实例帮助大家理解这部分知识,需要的朋友可以参考下
    2017-08-08
  • java  常见位逻辑运算符梳理

    java  常见位逻辑运算符梳理

    这篇文章主要介绍了java常见位逻辑运算符梳理,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参一下下面文章详细内容
    2022-08-08
  • httpclient模拟post请求json封装表单数据的实现方法

    httpclient模拟post请求json封装表单数据的实现方法

    下面小编就为大家带来一篇httpclient模拟post请求json封装表单数据的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • 浅谈Java并发编程中的线程

    浅谈Java并发编程中的线程

    这篇文章主要介绍了浅谈Java并发编程中的线程,操作系统运行一个程序,就会创建一个进程,在一个进程里可以创建多个线程,因此线程也叫做轻量级进程,需要的朋友可以参考下
    2023-08-08

最新评论