热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

JavaWeb中文编码问题实例讲解

在本篇文章里小编给大家整理的是关于JavaWeb中文编码问题方法的相关知识点内容,需要的朋友们参考下

一、JavaWeb编程中乱码的成因

因为计算机只认识0与1,在网络上要想传输各种字符就需要进行编码。而由于编码、传输、解码过程存在各种不确定性,导致乱码问题频发,成为困扰初学者的一大问题。本文就试图用最简单的示例解释乱码问题。

1.为什么会出现乱码问题

如同发电报一样,如果发报的采用一个密码本进行发报,而接收端采用另外的密码本进行解码,肯定会导致无法解码一样。如果在计算机网络中传输数据,发送端采用的编码和接收端采用的编码不一致就会导致乱码问题。

2.认识各种编码:

ASCII:

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

ISO-8859-1:

由于ASCII是美国标准,其收录了空格及94个“可印刷字符”,足以给英语使用。但是,其他使用拉丁字母的语言(主要是欧洲国家的语言),都有一定数量的附加符号字母,故需要使用ASCII及控制字符以外的区域来储存及表示。

为了解决这个问题,国际标准化组织(ISO)及国际电工委员会(IEC)联合制定的一系列8位字符集的标准ISO-8859,其全称ISO/IEC 8859,现时定义了15个字符集。除了使用拉丁字母的语言外,使用西里尔字母的东欧语言、希腊语、泰语、现代阿拉伯语、希伯来语等,都可以使用这个形式来储存及表示。

GBK/GB2312:

为了解决中文的显示和编辑问题,1980年中国国家标准总局发布了GB2312标准,全称是《信息交换用汉字编码字符集》,标准号是GB 2312—1980。GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。基本集共收入汉字6763个和非汉字图形字符682个。GB 2312的出现,基本满足了汉字的计算机处理需要,它所收录的汉字已经覆盖中国大陆99.75%的使用频率。但是对于人名、古汉语等方面出现的罕用字,GB 2312不能处理,这导致了后来GBK及GB 18030汉字字符集的出现。

1995年中国国家标准总局又颁布了《汉字编码扩展规范》(GBK)。GBK与GB 2312—1980国家标准所对应的内码标准兼容,同时在字汇一级支持ISO/IEC10646—1和GB 13000—1的全部中、日、韩(CJK)汉字,共计20902字。

国家标准GB18030-2005《信息技术 中文编码字符集》是我国继GB2312-1980和GB13000.1-1993之后最重要的汉字编码标准,是我国计算机系统必须遵循的基础性标准之一。 GB18030有两个版本:GB18030-2000和GB18030-2005。GB18030-2000是GBK的取代版本,它的主要特点是在GBK基础上增加了CJK统一汉字扩充A的汉字。GB18030-2005的主要特点是在GB18030-2000基础上增加了CJK统一汉字扩充B的汉字。GB18030-2005是我国自主研制的以汉字为主并包含多种我国少数民族文字(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)的超大型中文编码字符集强制性标准,其中收入汉字70000余个。中文的Windows操作系统默认使用GBK/GB2312编码。

Unicode:

很多传统的编码方式都有一个共同的问题,即容许电脑处理双语环境(通常使用拉丁字母以及其本地语言),但却无法同时支持多语言环境(指可同时处理多种语言混合的情况)。Unicode 是为了解决传统的字符编码方案的局限而产生的,例如ISO 8859所定义的字符虽然在不同的国家中广泛地使用,可是在不同国家间却经常出现不兼容的情况。Unicode的出现,能够使计算机实现跨语言、跨平台的文本转换及处理。

UTF-8:

因为Unicode编码使用2个字节存储一个字符。事实证明,对可以用ASCII表示的字符使用Unicode并不高效,因为Unicode比ASCII占用大一倍的空间,而对ASCII来说高字节的0对他毫无用处。为了解决这个问题,就出现了一些中间格式的字符集,他们被称为通用转换格式,即UTF(Unicode Transformation Format)。

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到4个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。

UTF-16:

UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为 "storage format")的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个定长表示。Java语言默认使用UTF-16作为内存的字符存储格式。

二、各种乱码的处理

乱码的处理问题因为产生原因不同,需要使用不同的方式进行处理,现就不同的问题分情况讨论如下:

1.响应中的乱码处理

A.使用字节输出流输出响应:

Stringdata="传智播客";

response.getOutputStream().write(data.getBytes());

经实测不会发生乱码问题,原因是String的getBytes()方法默认使用本地平台默认编码将字符串转换为字节数组,而我们中文的windows操作系统默认使用GBK编码。而在用户端,浏览器默认也使用操作系统默认编码解析网页,在windows系统下默认也是GBK。发送端及接收端编码一致,所以不会产生乱码问题。

由于UTF-8编码是国际上通用的编码,所以我们在做Web开发时,通常使用UTF-8编码。但是如果使用getBytes("UTF-8")得到字节数组,并发送给客户端,此时会产生乱码问题。原因是因为getBytes("UTF-8")实际是指定按照UTF-8编码将字符串转换成字节数组。而浏览器此时默认仍然使用本地平台默认编码进行解码就会发生乱码问题。

此时的显示效果如下:

此时可以使用以下方式解决乱码问题:

方法一:手工调整浏览器的编码

点击鼠标右键,在弹出菜单中选择编码,之后选择UTF-8编码。

方法二:使用html规范中的meta标签设置

添加上述代码后,文字显示正常。


方法三:使用Response对象的setHeader()方法设置Content-Type头

另外,按照HTTP协议的规定,如果指定了消息正文的MIME类型后,浏览器就必须按照MIME类型解析,所以可以通过设置响应消息头Content-Type的值为text/html,并指定参数charset=UTF-8来使浏览器使用UTF-8解析页面。


方法四:使用Response对象的setContentType()方法设置MIME类型及编码

由于方法三的使用频率比较高,所以在制定Servlet规范时,JCP组织抽取了一个比较简单的方法,此方法与方法三的原理相同,只是更简单,在实际工作中,我们通常使用此方法指定MIME类型。

B.使用字符输出流输出响应:

Response对象的getWriter()方法可以返回一个PrintWriter对象,输出的内容会暂存在缓冲区中。当响应结束时,Tomcat使用默认编码ISO-8859-1将Response对象的响应消息正文转换为二进制数据输出给客户端,而浏览器使用本地平台默认编码进行解码,从而导致乱码。



处理方式:使用response.setCharacterEncoding("UTF-8")方法告知Tomcat使用UTF-8而不是ISO-8859-1对响应消息正文进行编码。另外,还需要使用response.setContentType("text/html;charset=UTF-8")告知浏览器使用UTF-8编码解码传递过来的数据。


修改后的显示效果如下:


2.请求中的乱码处理

在用户提交表单时,浏览器会按照当前页面的编码设置对中文字符进行编码,并将内容生成请求消息发送给服务器进行解析。Tomcat服务器得到请求消息后,会依据表单数据的位置不同,做不同的处理。

当提交方法(method)是POST时,表单数据会置于请求消息正文中,Tomcat默认使用ISO-8859-1对此部分内容进行解码,此时需要使用Request.setCharacterEncoding("UTF-8")告知服务器使用UTF-8编码对请求消息正文进行解码。



当提交方法(method)是GET时,表单数据会置于请求消息行中,并使用URL标准编码方式进行二次编码。而Tomcat得到此部分数据后,会先使用URL标准规范进行解码,然后默认使用ISO-8859-1再进行二次解码。此时如果使用Request.getParamater()方法得到String字符串得到的是经过ISO-8859-1解码的字符串,故会发生乱码问题。对于此种情况,需要将得到的字符串重新按照ISO-8859-1打回字节数组,再重新解码方可。




3.COOKIE中的乱码处理;

因为COOKIE是分别使用Set-COOKIE和COOKIE消息头在响应和请求消息头中进行传输的,而HTTP协议中,响应消息和请求消息中只能使用英文字符,中文字符是不安全字符无法直接使用。故在将中文存入COOKIE中时,需要进行编码操作。我们可以使用URLEncoder工具类的encode()方法对中文进行编码,在读取时使用URLDecoder工具类的decode()方法进行解码。

使用URLEncoder.encode()方法对username字符串进行编码后再创建COOKIE对象如下图:


使用URLDecoder.decode()方法对username字符串进行解码如下图:


三、 总结

以上的例子只是抛砖引玉,只要我们能抓住问题的关键,了解乱码的本质,那么乱码什么的都是浮云。

以上就是关于JavaWeb中文编码问题方法的全部知识点,感谢大家的学习和对的支持。


推荐阅读
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
author-avatar
西岑村内徐老爷
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有