JavaWeb开发编码与乱码总结

简介:

自我总结

1.getBytes()和new String()方法

 ▇  public byte[] getBytes(Charset charset)方法

    这个方法是将字符串按指定的字符集进行编码,转换成字节数组。如果不指定字符集,默认采用

 系统自带的字符集。

    采用不同的字符集,对于同一个带有中文的字符串,得到的字节数组的是各不相同的。因为一个

 中文字符使用不同的编码方式,得到的字节长度是不同的。(可以通过将一个中文字符不同的编码转

 换成字节数组,然后再打印数组的长度)

    byte[] b_gbk = "中".getBytes("GBK");     //2个字节   
     byte[] b_utf8 = "中".getBytes("UTF-8");    //3个字节
     byte[] b_iso88591 = "中".getBytes("ISO8859-1");  //1个字节

    byte[] b_iso88591 = "中".getBytes("UNICODE");  //4个字节       

  String(byte[] bytes, Charset charset)

    通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String如果不指定字符集,

 默认采用系统自带的字符集。

 

     String s_gbk = new String(b_gbk,"GBK");        // 输出“中”
      String s_utf8 = new String(b_utf8,"UTF-8");       //  输出“中”      

      String s_iso88591 = new String(b_iso88591,"ISO8859-1");  //   输出乱码

     通过输出s_gbk、s_utf8和s_iso88591,会发现s_gbk和s_utf8都是"中",而只有s_iso88591是一个不被识别的字

   符(可以理解为乱码),为什么使用ISO8859-1编码再组合之后,无法还原"中"字?原因很简单,因为ISO8859-1编码

   的编码表根本就不包含汉字字符,当然也就无法通过"中".getBytes("ISO8859-1");来得到正确的"中"字在

   ISO8859-1中的编码值了,所以,再通过new String()来还原就更是无从谈起。

    因此,通过String.getBytes(String decode)方法来得到byte[]时,一定要确定decode的编码表中确实存在

   String表示的码值,这样得到的byte[]数组才能正确被还原。

   有时候,为了让中文字符适应某些特殊要求(如http header要求其内容必须为iso8859-1编码),可能会

  通过将中文字符按照字节方式来编码的情况,如:

  String s_iso88591 = new String("中".getBytes("UTF-8"),"ISO8859-1"),这样得到的s_iso8859-1

  字符串实际是三个在ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式

  String s_utf8 = new String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")来得到正确的中文汉

  字"中",这样就既保证了遵守协议规定、也支持中文。  

   上面这个过程的专业术语叫做逆向编解码,注意顺向编码的时候getBytes()采用utf-8,这个编码必需

  要支持中文。否则还是会出现乱码。 

2.常见字符集  

    ASCII( American Standard Code for Information Interchange ):美国标准信息交换码

      基本的 ASCII 字符集共有 128 个字符,其中有 96 个可打印字符,包括常用的字母、数字、标点符号等,

             另外还有 32 个控制字符(如回车、空格、换行等)。ASCII码使用7位2进制数表示一个字符,7位2进制数可以

             表示出2的7次方个字符,共128个字符。

      字母和数字的 ASCII 码的记忆是非常简单的。我们只要记住了一个字母或数字的 ASCII 码(例如记住 A 为

             65 , 0 的 ASCII 码为 48 ),知道相应的大小写字母之间差 32 ,就可以推算出其余字母、数字的 ASCII 

             码。

     0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符),如控制符:LF(换行)、CR(回

    车)、FF(换页)、DEL(删除)、BS(退格)、BEL(振铃)等;通信专用字符:SOH(文头)、EOT(文

    尾)、ACK(确认)等;ASCII值为8、9、10和13分别转换为退格、制表、换行和回车字符。它们并没有特定的

    图形显示,但会依不同的应用程序而对文本显示有不同的影响。

      32~126(共95个)是字符(32sp是空格),其中48~57为0到9十个阿拉伯数字,65~90为26个大写英文字

    母,97~122为26个小写字母,其余为一些标点符号、运算符号等。

      ANSI(MBCS)     

                    为了扩充ASCII编码,以用于显示本国的语言,不同的国家和地区制定了不同的标准,由此产生了

              GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 

             ANSI 编码,又称为"MBCS(Muilti-Bytes Charecter Set,多字节字符集)"。在简体中文系统下,ANSI 编码代

            表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码,所以在中文 windows下要转码成gb2312,gbk

            只需要把文本保存为ANSI 编码即可。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种

            语言的文字,存储在同一段 ANSI 编码的文本中。一个很大的缺点是,同一个编码值,在不同的编码体系里代表

            着不同的字。这样就容易造成混乱。导致了unicode码的诞生。其中每个语言下的ANSI编码,都有一套一对一的

            编码转换器,Unicode变成所有编码转换的中间介质。所有的编码都有一个转换器可以转换到Unicode,而

            Unicode也可以转换到其他所有的编码。

             ▇     GB2312

    GB 2312是一个简体中文字符集(详情请百度)

                     GB2312采用了二维矩阵编码法对所有字符进行编码

                     GB2312字符在计算机中存储是以其区位码为基础的,其中汉字的区码和位码分别占一个存储单元,每个

              汉字占两个存储单元。由于区码和位码的取值范围都是在1-94之间,这样的范围同西文的存储表示冲突。

             ▇   GBK

      GB 2312的出现,基本满足了汉字的计算机处理需要,但对于人名、古汉语等方面出现的罕用字,GB 

              2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。   

                     GBK编码标准兼容GB2312,简、繁体字融于一库。

                     GBK采用双字节表示,字符有一字节和双字节编码,00–7F范围内是一位,和ASCII保持一致。

             ▇    Big5

                      大五码是一种繁体中文汉字字符集(由来请百度)

    Unicode

                     如果有一种编码,将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个

             码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。这就是Unicode编

             码。   

                    Unicode固然统一了编码方式,但是它的效率不高,比如UCS-4(Unicode的标准之一)规定用4个字节存储

             个符号,那么每个英文字母前都必然有三个字节是0,这对存储和传输来说都很耗资源。(怪不得编程的时候不

             采用这种编码方式)

    ▇ UTF-8

      为了提高Unicode的编码效率,于是就出现了UTF-8编码。UTF-8可以根据不同的符号自动选择编码的长

             短。比如英文字母可以只用1个字节就够了。    

    ▇ ISO-8859-1

      ISO-8859-1编码是字节编码,向下兼容ASCII,它不支持中文,只支持几乎欧洲所有国家的语言。但它

             的使用十分的广泛,因为大多编程软件都是由外国人制作的。   

    ▇ Base64    

    一端发送GB2312编码->根据Base64规则->转换成ASCII码,接收端收到ASCII码->根据Base64规则-

             >还原到GB2312编码。   

3.Web打印中文数据和提交中文数据乱码问题(服务用的是tomcat)

   不管是从服务器向客户端打印数据,还是从客户端向服务器提交数据。数据的交互传输都是以流的方式进行的

             1)提交中文数据

                   在服务器端,可以通过request.getParameter()方法得到某一个表单数据,实际客户端传输的是按浏览器默

             认字符集编码之后的字节数据(表单数据.getBytes(浏览器默认字符编码)),数据到达了tomcat服务器,

             tomcat默认使用iso8859-1字符集来解码表单提交过来的字节数据,即执行new String(客户端提交的byte[]数

             组,tomcat默认解码字符集)。

      >>对于post提交,数据会先放到request缓冲区中,由于request缓冲区的默认字符集(iso8859-1)是可以进

            行修改的,通过request.setCharacterEncoding(decode)方法,那么tomcat在解码的时候就会按照指定字符集来

            解码。

                    例子:一般浏览器的默认编码字符集是utf-8,用post提交中文数据,会向服务器发送字节数组,“中

                              文”.getBytes("utf-8");在服务器端设置request.setCharacterEncoding("utf-8")。那么服务器通过

                              request.getParameter()得到的字符串就是new String("中文“.getBytes("utf-8"),"utf-8"),编解码方式

                              一致,自然不会出现中文乱码的情况了。

                     >>对于get提交数据不会放到request缓冲区中,所以无法修改tomcat解码的默认字符集iso8859-1,那

            么通过request.getParameter()方法得到字符串就是乱码了。            

                    例子:一般浏览器的默认编码字符集是utf-8,用post提交中文数据,会向服务器发送字节数组,“中

                              文”.getBytes("utf-8");那么服务器通过request.getParameter()得到的字符串就是new String("中

                              文“.getBytes("utf-8"),"iso8859-1"),编解码方式不一致,肯定就乱码了。

                    那么,应该如何解决get提交中文乱码的问题呢?

                    方式一:修改tomcat的server.xml文件,将URLEncoding改为utf-8(浏览器提交数据时采用的字符集)。

                             这种直接修改服务器配置的方式,类似于硬编码机制,一般不用这种方法。

                            wKioL1Wvq-bzR7z4AABR_1L4Jb4749.jpg

                    方式二:逆向编解码

                            data = URLEncoder.encode(data,"iso8859-1");

                            data = URLDecoder.decode(data,"utf-8");

                    方式三:逆向编解码的简写方式

                            data = new String(data.getBytes("iso8859-1"),"utf-8");

                    当然get提交这3种解决中文乱码的方法也同样适用于post提交。




         



















转载

1.那些年JavaWeb的各种中文乱码终极解决方法

   http://www.2cto.com/kf/201209/157773.html


2.java web 开发中的乱码解决方案自我总结

    http://blog.csdn.net/baoyinwang/article/details/7457087

3.字符集和字符编码(Charset & Encoding)

    http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html

4.深入分析 Java 中的中文编码问题

    http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/



      本文转自屠夫章哥  51CTO博客,原文链接:http://blog.51cto.com/4259297/1671871,如需转载请自行联系原作者





相关文章
|
2月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
8天前
|
自然语言处理 Java
Java中的字符集编码入门-增补字符(转载)
本文探讨Java对Unicode的支持及其发展历程。文章详细解析了Unicode字符集的结构,包括基本多语言面(BMP)和增补字符的表示方法,以及UTF-16编码中surrogate pair的使用。同时介绍了代码点和代码单元的概念,并解释了UTF-8的编码规则及其兼容性。
81 60
|
16天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
2天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
67 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
26天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
110 13
|
1月前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
67 10
|
25天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
60 2
|
1月前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
76 2
下一篇
开通oss服务