引言:

    在进行Web開始时。乱码是我们最常常遇到也是最主要的问题。有经验的程序员非常easy能解决,刚開始学习的人则easy被泥潭困住。

并且非常多时候。我们即使攻克了乱码问题也是不明就里。往往云里雾里。

    事实上乱码问题非常easy,就是client和server使用了不一样的字符集导致的。也就是我们发送文件时用的字符编码和解析文件的编码不一致。所以仅仅要搞清楚了我们的文件是怎么被编码和解码的解决乱码就非常easy了。分析乱码,我们从请求乱码和响应乱码来分析,请求乱码又须要依据GET和POST来单独分析。

请求乱码——GET

    请求的编码是由浏览器发出的。使用GET方法请求server信息时。依据HTTP协议规定,Request包是没有请求体的(也就是Request
Body不存在)
。所以我们仅仅能把请求參数放在URL中。因此使用GET方式与server通信,编码方面我们关心的重点是浏览器对URL的编码方式,和server对URL的解码过程。

关于URL

    URL是我们常常接触并不是常简单的一种技术,URL技术简单到它事实上就是一个字符串。

实际上URL的结构是非常复杂的,仅仅只是通常上使用方法比較简单而已。关于URL的具体介绍能够參考以下的文章:

我是传送门!。!

    URL的规范定义在RFC 1738文档中。通过URL我们能够获得通信协议、主机域名、处理port、应用路径、路径參数、查询參数、页面片段等信息。

比方:

    http://user:pass@example.com/a/b;q=1/c?d=2;sessionid=qewfewrwer#2

    依据上面的URL。我们能够得到例如以下信息:

Part

Data

serverAPI

Scheme

http

用req.getScheme

user

user

囧,不知道

pass

pass

囧,不知道

host address

example.com

req.getServerName

port

80

req.getServerPort

path

/a/b;q=1/c

req.getContextPath

query parameters

d=2;sessionid=qwefewrwer

req.getQueryString

fragement

2

    开发时,我们经经常使用到的就是path和query parameters。这两个參数,剩下的參数使用的比較少。只是在RESTful
API中,像路径參数的信息可能会用到。fragement用来在页面内进行锚点定位。(已经非经常见了)



浏览器对Path部分的编码

    path信息被用来匹配处理路径。一般设计上非常少在path中包含中文參数。RFC文档对于path的编码也没有明白规定。可是据其它文章的介绍。浏览器对Path的编码一般都会採用UTF-8编码,最新的URI标准已经定义了URI的编码採用UTF-8编码。

    定义:简单说path部分就是应用路径部分,就是URL去掉协议、域名、port和查询信息剩下的部分。



server对Path部分的解码:(三种方案)

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

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />

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

    假设不想使用这样的硬解码方案。还能够指定还有一个属性:useBodyEncodingForURI,这个属性用来告诉Web容器。假设request指定了解码方案,则使用request.setCharacterEncoding指定的编码来解码URL。

另外一种方案没有经过測试。假设有须要能够尝试下。

具体资料能够參考以下的Tomcat官方文档:

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

    此外。假设不想改动容器的全局配置。毕竟有时候容器里可能不止我们一个应用,那么我们还能够採用以下的做法来提取參数

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

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

浏览器对QueryParameter的编码

    查询參数和Path是不一样的,缺少查询參数,web容器是能够定位到我们的处理程序的,可是缺少path就不行。

另外,path和查询參数的保留字符是不一样的。

    定义:简单来说查询參数就是path后面紧跟的?后面的部分,用&来连接各个查询參数。

    因为Path和查询參数的不同,有些浏览器对查询參数的编码和path部分的编码是不一致的。

详细使用怎么编码的比較混乱。能够參考下以下的文章:

又一个传送门,啦啦啦!

    依据上面的文章总结的规律:

    (1)Path部分或者说除查询參数外的URL部分。各浏览器用UTF-8编码;

    (2)查询參数,各浏览器依据操作系统编码决定;

    上面的文章比較老了,规律可能不有用了,可是也能说明一定问题。对于某些文章说的,查询參数会依据页面编码来决定,我没有做实验。可是这样的结论肯定是片面的。原因例如以下:

    页面的meta參数是用来向浏览器说明页面编码的,其次。在使用POST Method发送数据的时候,浏览器会依据meta的编码来编码Request Body。而Get方式。我们在没有页面的时候也能够发起。所以浏览器根本找不到Meta标签,也就没法參考页面编码。

    浏览器对查询參数究竟使用哪种方式编码的,我没有找到专业、权威、可信的答案,可是我觉得这个还是详细情况详细分析。做个小实验即可了。

毕竟时代在进步。厂商们统一使用UTF-8编码的可能性比較大。并且后面有不依赖浏览器编码的解决方式。

server对QueryParameter的解码

    查询參数也是URL的一部分。所以Web容器对查询參数的解码比較明智,解码和path使用的是一样的方案的编码,所以解决方式也是一样的。



出现乱码:

    在处理查询參数时,我们经常使用req.getParameters();来获取某个參数。这种方法背后非常少有人关心它的工作原理。并且也不是必需。

这一部分是最easy出现乱码的,毕竟它里面的參数可能是用户输入的,并非我们设计的。

在GET方式下,出现这样的乱码不要慌张,首先我们要分析出,浏览器对查询參数究竟採用了哪种编码。

方法简单(也复杂),chrome下F12打开开发人员工具

   找到network标签,能够看到Request URL中显示的是k= %E4%B8%AD%E5%9B%BD,把%去掉,能够得到6个16进制数,百度下unicode码表。能够看到他们正好是“中”和“国”的unicode编码。所以能够推測浏览器使用的是UTF-8编码。这样的推断方式须要对字符编码比較熟悉。只是也不算非常难,找点字符编码的文章学学非常easy就能看出规律来。

    PS:不要通过浏览器的地址栏看URL编码,非常多浏览器的地址栏会对URL解码显示。

    之后,server端,首先确定下。你的Web容器对URL使用的解码方案,然后对应的选择String(param.getBytes(“ISO8895-1”,”UTF-8”))或者是useBodyEncodingForURI、URIEncoding方案就好了。



总结:

       使用GET方式出现乱码时,最基本的是找出浏览器对URL的编码方式,假设使用JS编程时。在浏览器能够使用encodeURIComponent函数对中文參数进行编码后再拼装參数。Java端使用URLDecoder.decode方法解码。JS端要进行两次编码,否则第一次的URL编码会被Web容器解码,获取的參数仍有可能是乱码。能够參考:

传送。!!!!

Java Web乱码分析及解决方式(一)——GET请求乱码的更多相关文章

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

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

  2. .atitit.web 推送实现解决方式集合(3)----dwr3 Reverse Ajax

    .atitit.web 推送实现解决方式集合(3)----dwr3 Reverse Ajax 1. 原理实现 1 2. Page  添加配置.添加回调函数dwr.engine.setActiveRev ...

  3. 分享下今天研究的流量上限DDos攻击分析和解决方式

    分享下今天研究的流量上限DDos攻击分析和解决方式 常常听到或者碰到某个站点被攻击.一般都是流量攻击.今天自己写了个程序測下相关的上限,程序仅仅简单做了个get html操作(不包括图片等资源文件). ...

  4. request、response 中文乱码问题与解决方式

    request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码:   response乱码指的是:服务器向浏览器发送的数据包含中文字符,浏览器中显示的是乱码: ...

  5. Linux转发性能评估与优化-转发瓶颈分析与解决方式(补遗)

    补遗 关于网络接收的软中断负载均衡,已经有了成熟的方案,可是该方案并不特别适合数据包转发,它对server的小包处理非常好.这就是RPS.我针对RPS做了一个patch.提升了其转发效率. 下面是我转 ...

  6. Linux转发性能评估与优化(转发瓶颈分析与解决方式)

    线速问题 非常多人对这个线速概念存在误解. 觉得所谓线速能力就是路由器/交换机就像一根网线一样. 而这,是不可能的.应该考虑到的一个概念就是延迟. 数据包进入路由器或者交换机,存在一个核心延迟操作,这 ...

  7. Android ListView异步载入图片乱序问题,原因分析及解决方式

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/45586553 在Android全部系统自带的控件其中,ListView这个控件算是 ...

  8. jsp页面中include静态html出现乱码问题的解决方式

    这个问题出现过两次,上次没有做好记录,今天又出现了.不过这两次的情景也不完全一致. 今天通过搜索找到这篇文章的解决方式很好,可供参考.原博客地址http://blog.csdn.net/izgnaw/ ...

  9. Java Web:主动和被动方式检测安全的框架

    对于某些敏感的系统例如支付.交易需要为其加固,有必要将可能的攻击情况考虑进来加以防范,于是有了这么一个简易的安全框架.在前辈的代码上( 详见 :http://blog.csdn.net/zhongwe ...

随机推荐

  1. 如何让你的.vue在sublime text 3 中变成彩色?

    作者:青鲤链接:https://www.zhihu.com/question/52215834/answer/129495890来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  2. MySQL灾备恢复在线主从复制变成主主复制及多源复制【转】

    生产主主复制(A<--->B),和灾备主从复制(B--->C).当生产出现问题时,数据写入切换到灾备数据库,待生产恢复后,将灾备回写到生产.步骤如下: 1.灾备与生产其中一台建立主主 ...

  3. oracle日期、转换函数

    转换函数 日期类型转换成字符类型 select to_char(sysdate) s1, --14-3月 -16        to_char(sysdate, 'yyyy-mm-dd') s2, - ...

  4. 防雪崩利器:熔断器 Hystrix 的原理与使用

    1.概述 分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应. 为了应对服务雪崩, 一种常见的做法是手动服务降级. 而Hystrix的出现,给我们提供了另一 ...

  5. 如何在Axure中使用FontAwesome字体图标

    Font Awesome为您提供可缩放的矢量图标,您可以使用CSS所提供的所有特性对它们进行更改,包括:大小.颜色.阴影或者其它任何支持的效果. FontAwesome应用在web网页开发中非常方便, ...

  6. 前后端分离之mockjs基本介绍

    安装与使用 # 安装 npm install mockjs #使用 Mock var Mock = require('mockjs') var data = Mock.mock({ // 属性 lis ...

  7. NOIP 2000 计算器的改良

    题面 NCL是一家专门从事计算器改良与升级的实验室,最近该实验室收到了某公司所委托的一个任务:需要在该公司某型号的计算器上加上解一元一次方程的功能.实验室将这个任务交给了一个刚进入的新手ZL先生. 为 ...

  8. Java编程的逻辑 (27) - 剖析包装类 (中)

    ​本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...

  9. Android中如何在代码中设置View的宽和高?

    Android中如何在代码中设置View的宽和高?https://zhidao.baidu.com/question/536302117.htmlhttps://blog.csdn.net/u0141 ...

  10. 体会 git 之优越性

    既生瑜,何生亮.已有subversion,何需git?先有firefox叱咤一时,何需chrome来搅局? 原本以为之前的解决方案已经能够满足现时的需求,但这是真正的事实吗?直到新颖的工具降临,才惊叹 ...