前言
接着上一篇继续,
查询字符串部分
首先 我们看一下对于查询字符串的获取, 详细内容可以参见上一篇的获取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”中获取编码
因此 对于查询字符串的解析这里做一个总结吧
如果配置了useBodyEncodingForURI为true, 则优先获取request.setCharacterEncoding配置的编码[也就是servlet, filter, action等等中配置的编码], 然后尝试获取”Content-Type”请求头中的编码, 否则 便取默认的编码[iso8859-1]进行解码
否则 使用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技术内幕”[许宁波著]