JavaWeb技术内幕三:JavaWeb中文编码问题
微信公众号【Java技术江湖】一位阿里 Java 工程师的技术小站。(关注公众号后回复”Java“即可领取 Java基础、进阶、项目和架构师等免费学习资料,更有数据库、分布式、微服务等热门技术学习视频,内容丰富,兼顾原理和实践,另外也将赠送作者原创的Java学习指南、Java程序员面试指南等干货资源)
Java作为跨平台语言,涉及到的编解码问题也比较多,我们来探讨一下HTTP请求如何控制编码格式。
几种常见的编码格式
为什么要编码
由于计算机只能看懂01,人类只能看懂字符,所以要进行编码和解码。
1 在计算机中,一个字节是最小的信息存储单元,而一个字节只能表示256个字符。
2 人类需要的符号远远超过256个。
如何翻译
各种语言需要交流,如何进行翻译呢,在计算机中提供了常见的翻译方式。比如ASCII,UTF-8等编码方式,他们可以被看做字典,可以让字节数组变成对应的字符。那么他们有什么区别呢。
1 ASCII码
一共有128个,用一个字节的低七位表示。
2 ISO
128个字符显然不够用,于是在ASCII基础上建立了ISO-8559编码。虽然仍是单字节,但可以表示256字符。
3 GB2312
是双字节编码,可以表示6763个汉字
4 GBK
它扩展了GB2312,功能表示21003个汉字。他和GB2312相互兼容
5 UTF-16
首先说下Unicode,ISO试图简历一个超语言词典,让所有语言都可以通过这个字典翻译。这是非常复杂的。
UTF-16定义了Unicode字符在计算机中的存储方法,UTF-16用两个字节来表示Unicode的转化格式,并且使用定长的方法,无论什么字符都可以用2个字节表示。
这大大简化了字符串操作,所以Java使用UTF-16作为内存字符的存储格式。
6 UTF-8
UTF-16统一使用两个字节表示一个字符,虽然很简单,但是很多字符只需要一个字节就可以表示了,相当于多处用了一倍的空间。
在网络带宽有限的情况下,没有必要。UTF-8使用变长技术,每个编码区有不同的字码长度。所有字符可以用1-6个字节组成。
如果是一个字节的字符那么就是ASCII码了
Java中需要编码的场景
io操作中存在的编码
字节流到字符流的互相转换需要用到编码
内存操作中的编码
使用String字符串和byte数组进行相互转换时,需要指定编码
Java中如何编解码
一般指定charsetname为指定编码格式即可。
各种编码实践
略
对几种编码格式的比较
1 对于中文字符,使用GBK好一点
2 对于Unicode字符,使用UTF-16的编码效率较高,转换更简单,进行字符串操作也更好,适合在磁盘和内存之间使用,但是不适合进行网络传输,因为双字节容易损坏,且占用空间大。
3 UTF-8更适合网络传输,UTF-8使用单字节存储,单个字符损坏不影响其他字符。
Java Web中设计的编解码
对于http网络传输,考虑压缩数据,减少网络传输量,但是有的压缩算法只减少字符数但是不减少字节数。
在计算机中,汉字的表示方式一般是一个字符使用两个字节来表示,所以Java的char类型也是16个bit,也就是2个字节。
JavaWeb可能出现编码转换的地方:
1 HTTP请求中的URI,Cookie,Post表单参数需要解码。
2 数据库的读写,文件读写需要编解码。
3 所有数据从socket返回时需要编码,浏览器解析页面需要解码。
URL的编解码
一个URL可以被分为好多个组成部分
http://localhost:8080/hello/servlet/黄蓬龙?name=h2pl
scheme domain port context servletpath pathinfo querystring
这部分中,url不包括querystring,uri则只包括hello/servlet/黄蓬龙,也就是context+servletpath+pathinfo。
所以uri只是定位资源,但是不包括网络协议
对于Tomcat而言,servlet会把这个url解析为一下几个部分。
事实上一部分配置是在server.xml配置文件中定义的。
1 port是配置文件中的connector port定义的。 2 context path是在配置文件中定义的 3 servletpath是web.xml的url-pattern中定义的。 4 pathinfo是我们具体请求的servlet 5 querystring是要传递的参数
pathinfo采用utf-8编码,querystring采用gbk编码
总结就是,url的编解码过程比较复杂,不是我们在应用中能控制的,所以尽量避免在url中使用非ASCII字符。
HTTP header的编解码
同理,默认使用ISO编码且不能改变,所以不用有非ASCII字符。
POST表单的编解码
post使用body传递数据,而header中设置了contenttype,所以我们根据这个编码格式进行编解码即可。
http body的编解码
上面讲过了。
另外JDBC的编码设置要和数据库内置的数据编码保持一致。
在JS中的编码问题
外部引入JS文件
引入时需要设置编码,否则可能乱码
JS的URL编码
略
其他需要编码的地方
1 xml可以设置头指定编码格式
2 velocity模板设置编码
3 jsp设置编码
常见问题分析
中文字符变乱码
编码解码的字符集不一致
一个汉字变成问号
将中文经过ISO编码(不支持中文)后会变成?
一个汉字变成两个问号
可能是多次编码过程中出错。
不正常的正确编码
略
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
金蝶K/3 报销相关SQL语句
金蝶K/3 报销相关SQL语句 use AIS20180607113701 select fopenid,* from dbo.t_XunTong_User where Fname ='' go use [KDAcctDB] select facctid,* from dbo.t_ad_kdAccount_gl where FAcctName ='landv' go http://127.0.0.1//LightApp/ExpenseManagement/ExpenseManagement.html#/Apps?logintype=yzj&openid=5b1f792be4b034d0608f8509&acctid=30&ispub=0 http://127.0.0.1//LightApp/ExpenseManagement/ExpenseManagement.html#/Apps?logintype=yzj&openid=5b025f90e4b0d301fd091e77&acctid=84&ispub=0 网名:浩秦; 邮箱:roo...
- 下一篇
Arch Linux 各种问题汇总
本机安装了Gnome 3.28.2这个版本的图形界面,一下问题是优化过程中遇到的问题,在此记录一下,可能会帮助到一些人。 用文件管理器打开文件 描述 浏览器下载了文件,右键点击文件--》在文件夹zhon中显示,打开的不是文件了管理器,而是别的,比如我的是VSCode 解决 $ xdg-mime default org.gnome.Nautilus.desktop inode/directory 桌面图标显示 不提供该项功能 GNOME 3.28之前,桌面图标通过Files在桌面上绘制一个透明的带图标的窗口实现。在GNOME 3.28中,该功能被移除,桌面图标不再在GNOME上可用。可能的方案包括使用Nemo(GNOME File的一个分支,目前仍支持桌面图标)或安装gnome-shell-extension-desktop-iconsAUR插件以部分复刻GNOME 3.26以下支持的桌面图标功能。更多信息请访问Arch forum thread。---https://wiki.archlinux.org/index.php/GNOME_(%E7%AE%80%E4%BD%93%E4%B8...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题