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 ...
随机推荐
- 纯文本-FileInputStream的编码与解码方式
前言:以下分析只针对纯文本 1.FileInputStream默认的编码方式就是文件的编码方式 即:源文件是什么编码方式,则利用FileInputStream默认读取的字节数组,就是什么编码方式. 例 ...
- class字节码结构(零:补充:class结构,常量池,字节码指令)
JVM高级特性与实践(五):实例探究Class类文件 及 常量池 JVM高级特性与实践(六):Class类文件的结构(访问标志,索引.字段表.方法表.属性表集合) JVM高级特性与实践(七):九大类字 ...
- jmeter-server中启动后端口总是不断在变化
1.首先找到这个文件打开: 2.修改两个地方如图: 第一个:server_port=xxxx 第二个:server.rmi.localport=xxxx 3.重启jmeter-server,这是在li ...
- 腾讯云 利用php + apache + mysql 搭建服务器环境
1.一键安装需要的软件源 yum install -y httpd php php-fpm mysql mysql-server php-mysql 1) httpd 即为 apache 2)php ...
- javascript数据结构与算法--二叉树遍历(先序)
javascript数据结构与算法--二叉树遍历(先序) 先序遍历先访问根节点, 然后以同样方式访问左子树和右子树 代码如下: /* *二叉树中,相对较小的值保存在左节点上,较大的值保存在右节点中 * ...
- activity和Task 有关的 Intent启动方式结合intent.setFlags()
通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activity的顺序: FLAG_ACTIVITY_NEW_TASK----简而言之,跳转到的activity根据情况,可能压在一个新建 ...
- Python字典按值排序、包含字典的列表按字典值排序的方法
operator.itemgetter函数 operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号(即需要获取的数据在对象中的序号),要注意,operator.i ...
- (转)MySQL字段类型详解
MySQL字段类型详解 原文:http://www.cnblogs.com/100thMountain/p/4692842.html MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间 ...
- Maven-pom.xml文件报错 Plugin execution not covered by lifecycle configuration
问题: Eclipse中新导入的项目pom.xml文件报错: Plugin execution not covered by lifecycle configuration: org.jacoco:j ...
- Zookeeper+ActiveMQ集群搭建
搭建三台虚拟机安装centos7.要提前安装好jdk环境 1.环境准备,搭建三台虚拟机ip分别是 192.168.192.130 192.168.192.131 192.168.192.134 Zoo ...