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

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

大家好,又见面了,我是全栈君。

引言:

    在进行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的具体介绍能够參考以下的文章:

我是传送门!。!大笑

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

    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打开开发人员工具

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

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

   找到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容器解码,获取的參数仍有可能是乱码。能够參考:

传送。!!!!

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115225.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ASP.NET Jumpstart:Media Share Library Starter Kit 简介

    ASP.NET Jumpstart:Media Share Library Starter Kit 简介

  • 网站被挂马了如何清理_网站在线挂马检测工具

    网站被挂马了如何清理_网站在线挂马检测工具
     
    您好,今天我们讲下挂马的危害和处理办法。挂马是常见的对网站和客户都影响巨大的危害之一。
          上海快网的经验是:如果是在访问出来的源文件的头上,或是最后有被加代码,这个一般是网站文件被要改了,或是ARP,如果是源文件的很多数据位置(中间),那一般是数据库被人挂了。
         不完全统计,90%的网站都被挂过马,挂马是指在获取网站或者网站服务器的部分或者全部权限后,在网页文件中插入一段恶意代码,这些恶意代码主要是一些包括IE等漏洞利用代码,用户访问被挂马

  • JVM参数调优总结 -Xms -Xmx -Xmn -Xss「建议收藏」

    “-Xmx1024m-Xms1024m-Xmn512m-Xss256k”——Java运行参数(转)JVM的堆的内存,是通过下面面两个参数控制的-Xms最小堆的大小,也就是当你的虚拟机启动后,就会分配这么大的堆内存给你-Xmx是最大堆的大小当最小堆占满后,会尝试进行GC,如果GC之后还不能得到足够的内存(GC未必会收集到所有当前可用内存),分配新的对象…

  • URL 规范 整理

    URL 规范 整理

  • 移动端开发之APP消息推送[通俗易懂]

    移动端开发之APP消息推送[通俗易懂]有这样一种场景,当你在手机APP上输入你的信息,会自动跳出一个弹窗,表示某任务已执行。最简单的一个例子就是当你输入手机号,点击获取验证码的时候,就会跳出一个对话框,说“验证码已发送到手机,请注意查收”,这些都是如何实现的。

  • Tomcat 日志概述[通俗易懂]

    Tomcat 日志概述[通俗易懂]1   Tomcat日志概述Tomcat日志信息分为两类:一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息。二是访问日志信息,它记录的访问的时间,IP,访问的资料等相关信息。2   Tomcat日志配置2.1 访问日志的配置默认tomcat不记录访问日志,如下方法可以使

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号