引言:

    在进行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. IDEA控制台乱码问题,原因解决方式,解决不了算我输

    IDEA 控制台乱码问题 文章目录 IDEA 控制台乱码问题 为了节省大家时间, 直接展示下我的编码配置方案 我的编码配置原则 我的编码配置 另外说一下几个重要但是和乱码无关的配置 乱码原因 解决方式 ...

  2. JSP中文乱码分析和解决

    转载自:http://bijian1013.iteye.com/blog/1841029 在JSP的开发过程中,经常出现中文乱码的问题. 首先了解一下Java中文问题的由来: Java的内核和clas ...

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

    request.response 中文乱码问题与解决方式 request乱码指的是:浏览器向服务器发送的请求参数中包含中文字符,服务器获取到的请求参数的值是乱码: response乱码指的是:服务器向 ...

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

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

  5. Eclipse 的常见报错、警告和原因分析、解决方式以及相关操作快捷键小结(持续更新)

    文章目录 前言 一.常见的三种类型错误 二.运行时错误 总结 前言 Eclipse 作为我们开发中最为常用的一款 IDE,功能齐全(虽然近几年被 IDEA 占尽了风头),但是最为基本的一些操作我们是要 ...

  6. Java中多线程访问冲突的解决方式

    Java中多线程访问冲突的解决方式 当时用多线程访问同一个资源时,非常容易出现线程安全的问题,例如当多个线程同时对一个数据进行修改时,会导致某些线程对数据的修改丢失.因此需要采用同步机制来解决这种问题 ...

  7. Java web中不同浏览器间导出Excel文件名称乱码问题解决方案

    Java web中不同浏览器间导出Excel文件名称乱码问题解决方案 参考文章: (1)Java web中不同浏览器间导出Excel文件名称乱码问题解决方案 (2)https://www.cnblog ...

  8. 在Tomcat中部署Java Web应用程序几种方式

    在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录.  一.静态部署       静态部署指的是我们在服务器启动之 ...

  9. OutOfMemoryError:Java堆空间–分析和解决方法

    java.lang.OutOfMemoryError:Java堆问题是在支持或开发复杂的Java EE应用程序时可能会遇到的最复杂的问题之一. 这篇简短的文章将为您提供此JVM HotSpot Out ...

最新文章

  1. FreeRTOS笔记2
  2. html页面加载转圈,纯CSS实现加载转圈样式
  3. HTML5本地存储不完全指南
  4. MySql 使用 EF Core 2.0 CodeFirst、DbFirst、数据库迁移(Migration)介绍及示例
  5. 栈空间和堆空间的区别
  6. 痛!做C#半年,挣的不如做AI1个月?”看到第二句泪目……
  7. 选择文件对话框、保存文件对话框、选择文件夹对话框
  8. Win10不能直接拖文件/Foxmail不能拖文件解决办法
  9. centos7磁盘备份和还原
  10. Springboot - 构建基于XML交互的Restful应用程序
  11. 韩国服务器性能排行榜,2019韩国云服务器排名
  12. 【CCIE考试流程、CCIE考试费用及CCIE考试地点】
  13. Azure NSG Flow Log 引发的自嗨 -- 日志 ETL 流式处理
  14. 英仕曼235年传奇之路从CTA策略鼻祖到全球最大上市对冲基金
  15. spring boot内嵌tomcat优雅的开启apr模式
  16. 大数据中技术的定义和特点
  17. 热加工作业考研题目答案分享——Joining processes 4
  18. 控制儿童在什么时段使用计算机,win10系统设置控制孩子用电脑的时间的图文步骤...
  19. 软件设计师——信息安全知识
  20. web期末大作业 使用HTML+CSS制作蓝色版爱宠之家带留言板(5页)

热门文章

  1. 性能测试搭建Jmeter分布式压测与监控
  2. Servlet 的三种创建方式
  3. 云熙板式家具参数化拆单软件免锁版_数控开料机拆单软件如何选择?
  4. post怎么用php,$_POST[''];怎么用
  5. 实现一个基于Vue的Button小组件
  6. 零基础开始学 Web 前端开发,有什么建议吗?
  7. ECC椭圆密码算法c语言实现,深入浅出椭圆加密算法ECC
  8. php简单的登录界面,PHP实现简单用户登录界面
  9. pyqt5 不报错退出_最新版本Python图形化开发环境Anaconda(Python3.7) +PyQT5+Eric6
  10. 陕西电大学位英语计算机考试,2017年电大学位英语复习【呕心沥血整理、电大考试必过】.doc...