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

引言:

    在进行Web开始时,乱码是我们最经常遇到也是最基本的问题,有经验的程序猿很容易能解决,初学者则容易被泥潭困住。而且很多时候,我们即使解决了乱码问题也是不明就里,往往云里雾里。

其实乱码问题很简单,就是客户端和服务器使用了不一样的字符集导致的。也就是我们发送文件是用的字符编码和解析文件的编码不一致。所以只要搞清楚了我们的文件是怎么被编码和解码的解决乱码就很简单了。分析乱码,我们从请求乱码和响应乱码来分析,请求乱码又需要根据GET和POST来单独分析。

请求乱码——GET

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

关于URL

    URL是我们经常接触并非常简单的一种技术,URL技术简单到它其实就是一个字符串。实际上URL的结构是很复杂的,只不过通常上用法比较简单而已。关于URL的详细介绍可以参考下面的文章:

我是传送门!!!

    URL的规范并定义在RFC 1738文档中。通过URL我们获得通信协议、主机域名、处理端口、应用路径、路径参数、查询参数、页面片段等信息。比如:

    http://user:[email protected]/a/b;q=1/c?d=2;sessionid=qewfewrwer#2

    根据上面的URL,我们可以得到如下信息:


Part


Data


服务器API


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编码中,像路径参数可能会用到。

浏览器对Path部分的编码

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

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

服务器对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编码的可能性比较大。而且后面有不依赖浏览器编码的解决方案。

服务器对QueryParameter的解码

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

出现乱码:

    在处理查询参数时,我们常用req.getParameters();来获取某个参数,这个方法背后很少有人关心它的工作原理,而且也没必要。这一部分是最容易出现乱码的,毕竟它里面的参数可能是用户输入的,并不是我们设计的。在GET方式下,出现这种乱码不要慌张,首先我们要分析出,浏览器对查询参数到底采用了哪种编码。方法简单(也复杂),chrome下F12打开开发者工具

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

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

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

总结:

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

传送!!!!!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 00:22:19

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

Java ConcurrentModificationException 异常分析与解决方案

Java ConcurrentModificationException 异常分析与解决方案http://www.2cto.com/kf/201403/286536.html java.util.ConcurrentModificationException 解决办法 http://blog.csdn.net/lipei1220/article/details/9028669 原因:Iterator做遍历的时候,HashMap被修改(bb.remove(ele), size-1),Iterato

jQuery框架+DWR框架实现的Java Web中的Ajax效果(异步请求,局部刷新)

一 简介和实现效果 这里用一个小例子来简单举例说明,做一个搜索引擎搜索提示效果,通过不断输入字符,然后在下方给出搜索提示.效果图如下: 通过上图可以看到,当输入一个"a"时,提示了很多内容,然后继续输入一个"e"后,提示的范围明显就变小了. 注:在文末我会给出完整源代码的下载链接,以供大家参考 二 具体实现 1 在eclipse for java ee中创建一个Java Web工程,然后导入相应的jar包,特别说明的是:这里要导入一个额外的dwr.jar.也就是说,

Java Web乱码分析及解决方案(三)——响应乱码

响应乱码 请求乱码是客户端向服务器发送数据时,服务器解码错误.响应乱码则是服务器处理完请求后,输出到浏览器的数据被浏览器错误解码造成的显示乱码,这类乱码是最常见也是最直接的.造成这类乱码的情况最直接的一点就是服务器对Content-Type响应报文设置错误. 页面编码: 我们的页面一般来说,可能是通过下面两种方式生成的,也就是常说的静态页面和动态页面: (1)静态页面:我们用记事本或其他IDE工具编写的页面(比如.html),这些页面在编写的时候就需要指定一个字符编码,比如我们指定为ISO-88

Java Web乱码分析及解决方案——POST请求

引言 GET请求的本质表现是将请求参数放在URL地址栏中,form表单的Method为GET的情况,参数会被浏览器默认编码,所以乱码处理方案是一样的.对于POST请求乱码,解决起来要比GET简单,我们关心的重点是在Request Body中. 请求乱码--Method方式 使用Method方式发送HTTP请求时,根据HTTP协议的规定,查询参数应该在Request的Body中,例如在Chrome下可以看到URL中不含有查询参数. 浏览器的编码 浏览器对POST的Request Body编码会采用

Java Web乱码分析及解决方案

1.  什么是URL编码. URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服务器上. 2.  URL编码规则. 每对name/value由&分开,每对来自表单的name/value用=分开.如果用户没有输入值的那个name依旧会出现不过就是没有值. URL编码是在字符ASCII码的十六进制数的前面加上%.例如\(她的十六进制数表示为5c)的URL编码就是%5c. 3.  简

java中文编码(字符集)分析-中文乱码分析及解决方案

 注:本文部分内容摘自网络,摘抄内容版权归原作者所有.  1.      背景知识 1.1.     Http协议 1.1.1.   URL和URI 1.1.2.   媒体类型定义 HTTP 在 Content-Type(14.17 节)和 Accept(14.1 节)头部域中使用因特网媒体类型 [17],为了提供打开和可扩展的数据类型和类型协议. media-type = type "/" subtype *( ";" parameter ) type = t

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

原文网址:http://www.2cto.com/kf/201403/286536.html 一.单线程 1. 异常情况举例 只要抛出出现异常,可以肯定的是代码一定有错误的地方.先来看看都有哪些情况会出现ConcurrentModificationException异常,下面以ArrayList remove 操作进行举例: 使用的数据集合: ? 1 2 3 4 5 6 7 List<string> myList = new ArrayList<string>(); myList.

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

Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历与各位网友分享解决这些问题的办法. 作为Internet最流行的编程语言之一,Java现正非常流行.我们的网络应用程序就主要采用Java语言开发,大体上分为客户端.服务器和数据库三个层次.在进入测试过程中,我们发现有一个程序模块系统内存和CPU资源消耗急剧增加,持续增长到出现java.lang.Ou

[Java Web]Mac OSX中MyEclipse的Console输出乱码的问题

一.问题说明 MAC系统,Myeclipse10那版(你懂的) 用Myeclipse自带的Tomcat6去在本机部署调试时,控制台中文乱码 之前采用新建Tomcat 7(系统Tomcat)暂时解决了,但是一直不明白为什么. 二.问题解决 说来说去,肯定是编码的问题,但是到底哪里加编码就是问题核心所在了 我无意中对比了下新建的Tomcat 7 server和自带的 Tomcat6,发现区别就在这里 看下对比 三.知识点 3.1 Mac下Myeclipse控制台中文乱码解决 版权声明:本文为博主原创