1.  什么是URL编码。

URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服务器上。

2.  URL编码规则。

每对name/value由&分开,每对来自表单的name/value用=分开。如果用户没有输入值的那个name依旧会出现不过就是没有值。

URL编码是在字符ASCII码的十六进制数的前面加上%。例如\(她的十六进制数表示为5c)的URL编码就是%5c。

3.  简单介绍乱码和http请求

其实做web开发乱码问题是经常出现的,有了上面编码的基础之后下面来看看乱码。

1)  乱码问题是web开发过程中经常遇到的问题,主要原因就是URL中使用了非ASCII码造成服务器后台程序解析出现乱码的问题。

2)  URL中最容易出现中文的地方就是在QueryString的参数值还有Servletpath中。

3)  简单用一个图来说明一下http请求的流程:

第一步:浏览器把URL经过编码送给服务器;

第二步:服务器把这些请求解码处理完毕之后将显示的内容进行编码发送给客户端浏览器;

第三步:浏览器按照指定的编码显示网页

post请求

详细剖析POST提交如何编码以及服务器如何解码以及乱码解决方案

对于POST方式,表单中的参数值对是通过request包发送给服务器,此时浏览器会根据网页的ContentType("text/html; charset=GBK")中指定的编码进行对表单中的数据进行编码,然后发给服务器。

在服务器端的程序中我们可以通过

Request.setCharacterEncoding()设置编码,然后通过

request.getParameter获得正确的数据。

这里出现乱码可以通过Request.setCharacterEncoding()直接解决。

get请求

对于GET方式,我们知道它的提交是将请求数据附加到URL后面作为参数,这样依赖乱码就会很容易出现,因为数据name和value很有可能就是传递的为非ASCII码。

当URL拼接后,浏览器对其进行encode,然后发送到服务器。具体规则见URL编码规则。

这里详细说一下encode的过程中容易出现的问题,在这个过程中我们要明白需要URL encode的字符一般都是非ASCII码字符,所以我们就能知道出现乱码主要是URL中附加了中文或特殊字符做成的,另一个要知道URL encode到底是以什么样的编码方式对字符进行编码的,其实这个编码方式是由浏览器决定的,不同的浏览器和同一浏览器的不同设置影响了URL的编码,所以为了避免我们不需要的编码,我们可以通过java代码或javaspcript代码统一进行控制。

完成了URL encode之后URL就成了ASCII范围内的字符了,然后就以iso-8859-1的编码方式转换为二进制随着请求头一起发送出去。

到了服务器之后,首先服务器会先用iso-8859-1进行解码,服务器获取的数据都是ASCII范围内的请求头字符,其中请求URL里面带有参数数据,如果是中卫或特殊字符,那么encode后的%XY(编码规则中的十六进制数)通过request.setCharacterEncoding()是不管用的。这时候我们就能发现出现乱码的根本原因就是客户端一般是通过用UTF-8或GBK等对数据进行encode的,到了服务器却用iso-8859-1方式decoder显然不行。

这里的解决方式有两种,

 通常上,我们的请求都会首先发给Web容器(下面以Tomcat为例),URL也会被Web容器解码,对于Tomcat容器来说,我们可以在conf/server.xml的connector标签中增加URL解码参数,默认容器对URL的使用ISO-8859-1解码。

  1. <Connector port="8080" protocol="HTTP/1.1"
  2. connectionTimeout="20000"
  3. redirectPort="8443" />

    上面的是Tomcat的默认设定,可以给标签添加URIEncoding属性来指定URL的解码方案。PS:标签写法是URI不是URL)

    如果不想使用这种硬解码方案,还可以指定另一个属性:useBodyEncodingForURI,这个属性用来告诉Web容器,如果request指定了解码方案,则使用request.setCharacterEncoding指定的编码来解码URL。

第二种方案没有经过测试,如果有需要可以尝试下。详细资料可以参考下面的Tomcat官方文档:

http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q2

    此外,如果不想修改容器的全局配置,毕竟有时候容器里可能不止我们一个应用,那么我们还可以采用下面的做法来提取参数

  1. String path = req.getServerPath();//自己手动提取,不适合配合框架
  2. path = new String(path.getBytes(“ISO8859-1”,”UTF-8”));//重新拼装

    上面的做法,我们要确定Web容器对URL的解码用的是ISO8859-1,因为不排除其他人修改了容器配置或容器配置本身比较奇葩的可能。

Java Web乱码分析及解决方案的更多相关文章

  1. Java Web乱码分析及解决方式(一)——GET请求乱码

    引言:     在进行Web開始时.乱码是我们最常常遇到也是最主要的问题.有经验的程序员非常easy能解决,刚開始学习的人则easy被泥潭困住. 并且非常多时候.我们即使攻克了乱码问题也是不明就里.往 ...

  2. Java Web乱码分析及解决方式(二)——POST请求乱码

    引言 GET请求的本质表现是将请求參数放在URL地址栏中.form表单的Method为GET的情况.參数会被浏览器默认编码,所以乱码处理方案是一样的. 对于POST请求乱码.解决起来要比GET简单.我 ...

  3. Java Web乱码原因与解决

    Java Web乱码原因与解决 一.了解编码常识: 1.ASCII 码 众所周知,这是最简单的编码.它总共可以表示128个字符,0~31是控制字符如换行.回车.删 除等,32~126是打印字符,可以通 ...

  4. Java ConcurrentModificationException 异常分析与解决方案

    Java ConcurrentModificationException 异常分析与解决方案http://www.2cto.com/kf/201403/286536.html java.util.Co ...

  5. java中文乱码分析整理

    在JavaWeb应用开发中,经常会出现页面中本该显示中文的地方却是乱码的情况.究其原因,主要是由于在Web组件之间.或Web组件与浏览器.与数据库所使用的字符集标准不统一,Web应用程序运行过程中,中 ...

  6. Java WEB 乱码解决大全

    来自 http://ligure.iteye.com/blog/ 中文乱码:在以后学习过程中全部采用UTF-8 1.文件的乱码 1.1.项目文本文件默认编码:        [右击项目]->[P ...

  7. [转]Java Web乱码过滤器

    本文转自http://blog.csdn.net/l271640625/article/details/6388690 大家都知道,在jsp里乱码是最让人讨厌的东西,有些乱码出来的莫名其妙,给开发带来 ...

  8. 【转】Java ConcurrentModificationException 异常分析与解决方案--还不错

    原文网址:http://www.2cto.com/kf/201403/286536.html 一.单线程 1. 异常情况举例 只要抛出出现异常,可以肯定的是代码一定有错误的地方.先来看看都有哪些情况会 ...

  9. Java内存泄漏分析与解决方案

    Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...

随机推荐

  1. 【读书笔记】iOS-关闭键盘的2种方法

    一种是通过使用键盘上的return键关闭键盘,一种是通过触摸背景关闭键盘. 参考资料:<iOS7开发快速入门>

  2. 【Python】keras卷积神经网络识别mnist

    卷积神经网络的结构我随意设了一个. 结构大概是下面这个样子: 代码如下: import numpy as np from keras.preprocessing import image from k ...

  3. Hibernate中Session.get()方法和load()方法的详细比较

    一.get方法和load方法的简易理解  (1)get()方法直接返回实体类,如果查不到数据则返回null.load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用 ...

  4. excel文件使用navicat工具导入mysql的方法

    1.在excel文件的sheet上,第1行下面插入一行,对应DB里面的字段名称,方便后面导入时做字段匹配: 2.使用Navicat ,打开工具,选择表所在的数据库,然后点击数据库名字,右键Tables ...

  5. Linux中 /proc/[pid] 目录各文件简析

    Linux 内核提供了一种通过 proc 文件系统,在运行时访问内核内部数据结构.改变内核设置的机制.proc 文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系 ...

  6. 理解lua中 . : self

    前言 在LUA中,经常可以看到:. self,如果你学习过Java或C#语言,可以这样理解 .对于c#和java的静态方法 :相当于是实例方法 今天在CSDN上看到一篇博客写的很清楚,转载过来 原文出 ...

  7. react的新手基础知识笔记

    <!DOCTYPE html> <html> <head> <script src="../build/react.js">< ...

  8. [Python] 启动 uiautomatorviewer2之后,连接成功后重新 reload画面时提示 ('Connection aborted.', error(10054, ''))

    [问题] 出现该问题不管是重启手机还是启动手机里面 uiautomator的服务,都无济于事,只有通过下面方法进行重新初使化方能解决问题 [解决方法] 在命令窗口执行如下命令 python -m ui ...

  9. Oracle修改表空间为自动扩展

    https://gqsunrise.iteye.com/blog/2015692 1.数据文件自动扩展的好处1)不会出现因为没有剩余空间可以利用到数据无法写入2)尽量减少人为的维护3)可以用于重要级别 ...

  10. Python datetime.md

    datetime datetime模块包含了一些用于时间解析.格式化.计算的函数. Times 时间值由time类来表示, Times有小时, 分, 秒和微秒属性. 以及包含时区信息. 初始化time ...