12 Tomcat编码问题02 queryString 和postData部分

前言

接着上一篇继续,

查询字符串部分

首先 我们看一下对于查询字符串的获取, 详细内容可以参见上一篇的获取requestURI的截图

InternalInputBuffer. parseRequestLine
这里写图片描述

然后 我们再来看一下request.getParameter的逻辑

Request.getParameter
这里写图片描述

然后 我们再来看一下request.queryString的使用的地方
这里写图片描述

和request.requestURI类似, 红色方框的为三个平行的逻辑, 绿色箭头的操作为只读操作, FormAuthenticator中的业务逻辑我不了解

那么问题来了, request.queryString 是如何和parameter”勾搭”上的呢

Request. Request
这里写图片描述

看到了吧, 那么 我们继续主线吧

org.apache.catalina.connector.Request.parseParameters
这里写图片描述

这里我们需要关注的逻辑有两点, 第一, 配置编码, 配置了两种编码, 第二, 解析查询字符串

首先 我们先看关于查询字符串的解析吧, 至于编码是如何配置的, 我们可以放到本节末尾, 做一个总结

Parameters. handleQueryParameters
这里写图片描述

这里需要关注三点,

首先 handleQueryParameters的逻辑只会解析handle一次, [请详见后面的”request. setCharacterEncoding问题”]

第二 我们这里decodedQuery是queryMB的一个副本, 因此 对于decodedQuery的操作不会影响到queryMB, 以便于 request.getQueryString的相关业务[对于获取到的字符串也没有进行特别的解码, 默认的iso8859-1[MessageBytes.toString] ]

第三 就是解析参数的编码了, 注意 这里使用的是queryStringEncoding,, 我们的结论就会从这个变量中揭晓

Parameters. setQueryStringEncoding
这里写图片描述

我们这里需要关注的是后两个, 对于前两个, FormAuthenticator的逻辑我不了解, 第二个 似乎是处理一些400啊, 错误了之后的逻辑[有兴趣的朋友可以执行研习]

首先说说CoyoteAdapter. service, 因为他会先被执行
这里写图片描述

首先配置了server.xml的Connector的URIEncoding配置[可能为null]

org.apache.catalina.connector.Request.parseParameters
这里写图片描述

可以看出需要server.xml中配置了useBodyEncodingForURI为true, 才会将”getCharacterEncoding”获取到的编码配置到parameters中

org.apache.catalina.connector.Request. getCharacterEncoding
这里写图片描述

Request. getCharacterEncoding
这里写图片描述

这里的Request.characterEncoding, 可以通过程序中的request.setCharacterEncoding进行配置, 否则便尝试从请求头”Content-Type”中获取编码

因此 对于查询字符串的解析这里做一个总结吧

  1. 如果配置了useBodyEncodingForURI为true, 则优先获取request.setCharacterEncoding配置的编码[也就是servlet, filter, action等等中配置的编码], 然后尝试获取”Content-Type”请求头中的编码, 否则 便取默认的编码[iso8859-1]进行解码

  2. 否则 使用URIEncoding的编码对查询字符串进行解码

对于上面的两点, 第一点是不论什么场景, 都会选择一种编码

对于第二点, 却可能出现server.xml的Connector的URIEncoding属性不存在的情况啊, 这时候 应该怎么办? 抛出异常吗??

不会的, 咋个会因为这么小的事情来抛异常呢, 这时候 tomcat有相关的”容错”策略

Parameters. handleParameters
这里写图片描述
Parameters. processParameters
这里写图片描述
Parameters. getCharset
这里写图片描述

看到了吧, 如果没有配置useBodyEncodingForURI为true, 并且没有配置URIEncoding, 则采用默认的字符集[iso8859-1]


post的键值对数据的处理

org.apache.catalina.connector.Request. parseParameters
这里写图片描述

Parameters. processParameters
这里写图片描述
看到这里 似乎答案又要解开了呢

Prameters. setEncoding
这里写图片描述

配置Parameters. encoding的地方 只有这一处, 其他的使用的地方均是只读操作

org.apache.catalina.connector.Request.parseParameters
这里写图片描述

看到了吧, 对于post的键值对数据的总结一下

优先获取request.setCharacterEncoding配置的编码[也就是servlet, filter, action等等中配置的编码], 然后尝试获取”Content-Type”请求头中的编码, 否则 便取默认的编码[iso8859-1]进行解码


1. requset. setCharacterEncoding问题

关于requset. setCharacterEncoding, 存在一个容易疏忽的地方, 案例如下

这里写图片描述

上面的截图 来自于 “深入分析Java Web技术内幕”[3.4.3 POST表单的编解码][许宁波著], 我也觉得这是一个比较容易疏忽的地方, 再配置了request. setCharacterEncoding 如果 是在是没有找到问题之所在, 可以 思考一下是否是这个问题

上面的问题 是由于”Parameters.handleQueryParameters” 只会解析一次, 而在”request. setCharacterEncoding”之前就已经参数解析过了, 因此 没有达到想要的目的

参考
http://www.xuebuyuan.com/1287083.html
http://www.cnblogs.com/chenssy/p/4220400.html
“深入分析Java Web技术内幕”[许宁波著]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值