Java Web中涉及的编解码
用户从浏览器发起一个HTTP请求,存在编码的地方是URL、Cookie、Paramiter。服务器端接收到HTTP请求后要解析HTTP协议,其中URL、Cookie和POST表单参数要解码,服务器端可能还需要读取硬盘数据(数据库、文件),这些数据都可能存在编码问题。当Servlet处理完所有请求的数据后,需要将这些数据再编码通过Socket发送到用户请求的浏览器里,再经过浏览器解码成为文本。这些过程用图表示如下:

1.URL的编解码

为了验证浏览器是怎么编码URL的,我们选择FireFox浏览器并通过HTTPFox插件观察请求的URL的实际内容:

从结果上看,PathInfo是UTF-8编码,而QueryString是GBK编码。至于为什么有%,是由URL的编码规范FRC3986规定:浏览器编码URL将非ASCII字符按照某种编码格式编码成16进制数字后将每个16进制表示的字节前加上“%”。
从上面的测试结果可知,浏览器对PathInfo和QueryString的编码是不一样的,不同的浏览器对PathInfo的编码也可能不一样。如Chrome会对请求“http://localhost:8080/中国?中国”转变为“http://localhost:8080/%E4%B8%AD%E5%9B%BD?%E4%B8%AD%E5%9B%BD”,这里PathInfo和QueryString的编码是一样的,都是UTF-8编码。
2.HTTP Header的编解码
当客户端发起一个HTTP请求时,除了上面的URL外还可能会在Header中传递其他的参数,如Cookie、redirectPath等,这些用户设置的值很可能也会存在编码问题。
在Tomcat中,对Header中的项进行解码是在调用request.getHeader时进行的,如果请求的Header项没有解码则调用MessageBytes的toString方法,这个方法将从byte从char的转化使用的默认编码是ISO-8859-1,而我们也不能设置Header的其他解码格式,所以如果你设置的Header中非ASCII字符解码肯定会有乱码。
我们在添加Header时也是同样的道理,不要在Header中传递非ASCII字符,如果一定要传递可以先将字符用org.apache.catalina.util.URLEncoder编码,然后再添加到Header中,这样在浏览器到服务器的传递中就不会丢失信息了,我们在访问这些项时再按照相应的字符集解码就好了。
3.POST表单的编解码
POST表单参数传递方式与QueryString不同,它是通过HTTP的BODY传递到服务端的。当我们在页面上点击提交按钮时浏览器首先将根据页面的ContentType的Charset编码格式对表单填的参数进行编码,然后提交到服务器端。在服务器端同样也是用ContentType中的字符集进行解码。所以通过POST表单提交的参数一般不会出现问题,而且这个字符集编码是我们自己设置的。
另外,针对multipart/form-data类型的参数,也就是上传的文件编码,同样也使用ContentType定义的字符集编码。值得注意的地方是,上传文件是用字节流的方式传输到服务器的本地临时目录,这个过程并没有涉及字符编码,而真正编码是在将文件内容添加到parameters中时,如果用这个不能编码将会用默认编码ISO-8859-1来编码。
4.HTTP BODY的编解码
当用户请求的资源服务端已经成功获取后,这些内容将通过Response返回给客户端浏览器,这个过程先要经过编码再到浏览器进行解码,浏览器根据HTML的<meta HTTP-equiv=“Content-Type” content=”text/html; charset=GBK”>中的charset来解码。如果没有定义,那么浏览器将会使用默认的编码来解码。
访问数据库都是通过客户端JDBC驱动来完成的,用JDBC来存取数据要和数据的内置编码保持一致,可以通过设置JDBC URL来指定。
5.JS中的编解码
html文件本身中的js的编码和当前页面中的Content-Type保持一致。
对于采用<script src=”script.js”/>类型引入的js文件,浏览器就会以当前这个页面的默认字符集解析这个JS文件,如果外部的JS文件的编码格式与当前页面的编码格式一致,那么可以不设置这个charset。但是如果script.js文件的编码格式与当前页面的不一致,就必须要指定对应的字符集,要不然对于非ASCII字符就会出现乱码。
6.其他需要编码的地方
除了URL和参数编码问题外,在服务端还有很多地方可能存在编码,如可能需要读取XML、Velocity模板引擎、JSP或者从数据库读取数据等。

参考资料:《深入分析Java Web技术》
Java Web中涉及的编解码的更多相关文章
- JAVA WEB 中涉及的编解码
1.对URL解码 1)URI部分解码:<Connector URIEncoding="UTF-8" /> 2)QueryString解码要么是 Header 中 Con ...
- 深入分析Java Web中的编码问题
编码问题一直困扰着我,每次遇到乱码或者编码问题,网上一查,问题解决了,但是实际的原理并没有搞懂,每次遇到,都是什么头疼. 决定彻彻底底的一次性解决编码问题. 1.为什么要编码 计算机的基本单元是字节, ...
- 【中文乱码】深入分析 Java Web 中的中文编码问题
深入分析 Java Web 中的中文编码问题 1.几种常见的编码格式 1.1 为什么要编码 在计算机中存储信息的最小单元是 1 个字节,即 8 个 bit, 所以能表示的字符范围是 0 ~ 255 个 ...
- JAVA WEB 中的编码分析
JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...
- 第三章 深入分析Java Web中的中文编码问题
3.1 几种常见的编码格式 3.1.1 为什么要编码 一个字节 byte只能表示0~255个符号,要表示更多的字符,需要编码. 3.1.2 如何翻译 ASCII码:有128个,用一个字节的低7位表示. ...
- Java web中常见编码乱码问题(一)
最近在看Java web中中文编码问题,特此记录下. 本文将会介绍常见编码方式和Java web中遇到中文乱码问题的常见解决方法: 一.常见编码方式: 1.ASCII 码 众所周知,这是最简单的编码. ...
- Java Web 中 过滤器与拦截器的区别
过滤器,是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法u ...
- Java web中常见编码乱码问题(二)
根据上篇记录Java web中常见编码乱码问题(一), 接着记录乱码案例: 案例分析: 2.输出流写入内容或者输入流读取内容时乱码(内容中有中文) 原因分析: a. 如果是按字节写入或读取时乱码, ...
- 解决java web中safari浏览器下载后文件中文乱码问题
解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...
随机推荐
- 读DEDECMS找后台目录有感
本文作者:红日安全团队——Mochazz 早上看了先知论坛的这篇文章:解决DEDECMS历史难题–找后台目录 不得不说作者思路确实巧妙,作者巧妙的利用了Windows FindFirstFile和织梦 ...
- maven添加仓库没有的jar包
mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.4.0 -Dpackaging= ...
- 微服务是"银弹"吗?
前言:所谓"银弹",本意是用金属银做成的子弹:在古老的传说里它是杀死狼人的有效武器.在著作<人月神话>也有描述.微服务是当前软件界流行的名词,那么它能成为像银弹一样厉害 ...
- nodeJS搭建一个简单的(代理)web服务器
前端获取数据时经常遇见跨域问题,以前一直用nginx做反向代理.最近在用vuejs,发现webpack-dev-server的代理简单好用.于是仿照写了一个简单的web服务器,用于非webpack的项 ...
- WebDriverAPI(9)
操作JavaScript的Alert窗口 测试网址代码 <html> <head> <title>你喜欢的水果</title> </head> ...
- FlowPortal-BPM——功能:判断数据库表中字段是否重复并阻止提交或保存
一.JS添加代码,判断是否有OnSubmit事件 文件位置:YZSoft/Forms/src/Validator.js //=====判断是否有OnSubmit事件===== if (typeof ( ...
- (转)Python全能自动化开发环境软件之pyenv的安装说明
原文:http://www.magedu.com/73921.html pyenv,是一款特别好用的Python版本管理器,程序员可以建立不同的目录,在不同的目录里分别运行不同版本的Python, 并 ...
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)(略有修改)
对应项目的代码地址为:https://github.com/liuxiaoming7708/springboot-dubbo-parent Dubbo与Zookeeper.SpringMVC整合和使用 ...
- SocketIo+SpringMvc实现文件的上传下载
SocketIo+SpringMvc实现文件的上传下载 socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示: GIT地址 ...
- MySQL查询时区分大小写
在创建MySQL数据库时,下面这些参数可供我们选择:*_bin: 表示的是binary case sensitive collation,也就是说是区分大小写的 *_cs: case sensitiv ...