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

来源:互联网 发布:淘宝私人定制在哪里 编辑:程序博客网 时间:2024/06/06 20:26

前言

接着上一篇继续,

查询字符串部分

首先 我们看一下对于查询字符串的获取, 详细内容可以参见上一篇的获取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技术内幕”[许宁波著]

0 0
原创粉丝点击