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中文编码问题方法的全部知识点,感谢大家的学习和对我们的支持。

(0)

相关推荐

  • JavaWeb 使用Session实现一次性验证码功能

    表单 <form action="loginServlet" method="post"> 请输入验证码:<input type="text" name="code" /> <img src="getCodeServlet" /><br /> <button type="submit">提交</button> <

  • JavaWeb JDBC + MySql 通讯录实现简单的增删改查功能案例详解

    本文实例讲述了JavaWeb JDBC + MySql 通讯录实现简单的增删改查功能.分享给大家供大家参考,具体如下: 开发工具:Eclipse + Navicat 项目源码:Github:https://github.com/Sunjinhang/JavaWeb 一.新建项目 在Eclipse中新建一个Web项目,至于如何新建Web项目以及如何添加Tomcat服务器的就不赘述了,项目的目录如下 最终实现的效果如下所示: 点击新增可以进行联系人的新增,点击修改/删除可以进行 联系人的修改和删除

  • JavaWeb乱码问题的终极解决方案(推荐)

    前言 经常有读者在公众号上问 JavaWeb 乱码的问题,昨天又有一个小伙伴问及此事,其实这个问题很简单,但是想要说清楚却并不容易,因为每个人乱码的原因都不一样,给每位小伙伴都把乱码的原因讲一遍也挺费时间的,因此,松哥今天决定写一篇文章,和大伙好好捋捋 JavaWeb 中的乱码问题. 对于一些老司机而言,其实并不太容易遇到乱码问题,但是对于一些新手来说,乱码几乎是家常便饭,而且每当乱码时,网上搜了一大堆解决方案,发现自己的问题还是没能解决,其实这就是平时研究代码不求甚解导致的,乱码问题,也要去分

  • javaWeb使用验证码实现简单登录

    本文实例为大家分享了javaWeb使用验证码实现简单登录的具体代码,供大家参考,具体内容如下 简单的流程图 1.用户给第一次访问login.jsp页面时,会想服务器发送两个请求,一个请求是显示图片,还有一个是显示表单 2.第一个请求发送后 服务器中verifyServlet处理,随机生成验证码图片,并保存到session中,然后响应给客户端 3.第二个请求后 服务器LoginServlet处理,获取表单验证码,以及session中的验证码,再判断两个验证码是否相等,相等就向下执行即 succes

  • JavaWeb中文编码问题实例讲解

    一.JavaWeb编程中乱码的成因 因为计算机只认识0与1,在网络上要想传输各种字符就需要进行编码.而由于编码.传输.解码过程存在各种不确定性,导致乱码问题频发,成为困扰初学者的一大问题.本文就试图用最简单的示例解释乱码问题. 1.为什么会出现乱码问题 如同发电报一样,如果发报的采用一个密码本进行发报,而接收端采用另外的密码本进行解码,肯定会导致无法解码一样.如果在计算机网络中传输数据,发送端采用的编码和接收端采用的编码不一致就会导致乱码问题. 2.认识各种编码: ASCII: ASCII(Am

  • JavaWeb文件上传下载实例讲解(酷炫的文件上传技术)

    一.课程概述 在Web应用系统开发中,文件上传功能是非常常用的功能,今天来主要讲讲JavaWeb中的文件上传功能的相关技术实现,并且随着互联网技术的飞速发展,用户对网站的体验要求越来越高,在文件上传功能的技术上也出现许多创新点,例如异步上传文件,拖拽式上传,黏贴上传,上传进度监控,文件缩略图,大文件断点续传,大文件秒传等等. 本课程需要的基础知识: 了解基本的Http协议内容 基本IO流操作技术 Servlet基础知识 javascript/jQuery技术基础知识 二.文件上传的基础 对于文件

  • java web response提供文件下载功能的实例讲解

    webapp项目的结构如下图: download.html文件的内容如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>资源下载:</h1> <p> 单纯地使用a标签时,只有浏览器不能解析的文

  • Java调用R语言实例讲解

    R是统计计算的强大工具,JAVA是做应用系统的主流语言.JAVA负责系统的构建,R用来做运算引擎,从而实现应用型和分析性相结合的系统. 一.Rserve(远程通信模式) Rserve是一个基于TCP/IP的服务器,通过二进制协议传输数据,可以提供远程连接,使得客户端语言能够调用R. Rserve作为一个package发布在CRAN上,可以直接使用install.packages("Rserve")进行安装.需要使用时在R控制台下加载该包,然后输入命令Rserve(),开启服务器就可以供

  • Java实例讲解文件上传与跨域问题

    目录 了解MultipartFile接口 文件上传业务代码 Controller类 Service类 修改nginx配置 如何绕过网关 1.在网关中配置白名单 2.在nginx做转发 解决上传文件出现跨域问题 写配置类CorsFilter 在nginx配置中配置请求实体大小 Java文件上传实例并解决跨域问题 目在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传功能的实现. 了解MultipartFile接口 我们实现文件的上传用到了Spring-

  • Springboot实例讲解实现专业材料认证管理系统流程

    目录 一,项目简介 二,环境介绍 三,系统展示 四,核心代码展示 五,项目总结 一,项目简介 这是一个基于java的毕业设计项目,毕设课题为springboot框架的知识产权服务平台系统, 是一个采用b/s结构的javaweb项目, 开发工具eclipsei/eclipse, 项目框架jsp+springboot+mybatis, 知识产权服务平台系统采用mysql进行数据存储, 并基于mybatis进行了orm实体关系映射, 该知识产权服务平台系统系统通过模块化实现,支持多角色权限管理系统,

  • django定期执行任务(实例讲解)

    要在django项目中定期执行任务,比如每天一定的时间点抓取数据,刷新数据库等,可以参考stackoverflow的方法,先编写一个manage.py命令,然后使用crontab来定时执行这个命令. 定制manage.py命令 app可以使用manage.py注册自己的命令,比如要在polls这个app中定制一个closepoll命令,要先向polls文件夹中添加一个management/commands的目录: polls/ __init__.py models.py management/

  • jq源码解析之绑在$,jQuery上面的方法(实例讲解)

    1.当我们用$符号直接调用的方法.在jQuery内部是如何封装的呢?有没有好奇心? // jQuery.extend 的方法 是绑定在 $ 上面的. jQuery.extend( { //expando 用于决定当前页面的唯一性. /\D/ 非数字.其实就是去掉小数点. expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready wit

  • jquery之基本选择器practice(实例讲解)

    一.在输入框中输入数字,点击按钮,实现对应事件的功能. html代码: <input id="txt1" type="text" value="2" /> <input id="Button5" type="button" value="改变大于N的行背景为绿色" /> jQuery代码: //改变大于N的行背景为绿色 $("#Button5"

  • python爬取安居客二手房网站数据(实例讲解)

    是小打小闹 哈哈,现在开始正式进行爬虫书写首先,需要分析一下要爬取的网站的结构:作为一名河南的学生,那就看看郑州的二手房信息吧! 在上面这个页面中,我们可以看到一条条的房源信息,从中我们发现了什么,发现了连郑州的二手房都是这么的贵,作为即将毕业的学生狗惹不起啊惹不起 还是正文吧!!!由上可以看到网页一条条的房源信息,点击进去后就会发现: 房源的详细信息.OK!那么我们要干嘛呢,就是把郑州这个地区的二手房房源信息都能拿到手,可以保存到数据库中,用来干嘛呢,作为一个地理人,还是有点用处的,这次就不说

随机推荐