eagleshi 发表于 2015-8-10 15:49:51

Tomcat编码配置解疑

  环境:tomcat6.0.23 jdk 1.6
  相关参考:
  http://tomcat.apache.org/tomcat-7.0-doc/config/ajp.html
  http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
  
  影响编码的环境:server.xml中Connector节点的URIEncoding与useBodyEncodingForURI参数,http请求头content-type charset=xxx中的charset值,servlet request的setCharacterEncoding参数值以及setCharacterEncoding的调用时机这五个环境参数;
  请求参数解析的时间(tomcat环境):第一次请求request参数时,且每次用户请求中有且只有一次参数解析。换而言之,参数的初始化是Lazy的,且会一次性初始化所有请求中包含的参数字段与对应的取值;
  
  get请求测试用例 A:
  http://localhost:8080/test?addr=上海
  请求头:content-type charset=utf-8;
  server.xml配置<Connector URIEncoding="utf-8" useBodyEncodingForURI="true" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  服务端收到请求后的处理方式:servlet中未调用request.setCharacterEncoding("utf-8")
  结果:getParameter("addr") 解码正确
  
  get请求测试用例 B:
  http://localhost:8080/test?addr=上海
  请求头:(无 content-type charset=utf-8;)
  server.xml配置<Connector URIEncoding="utf-8" useBodyEncodingForURI="true" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  服务端收到请求后的处理方式:同A
  结果:getParameter("addr") 乱码
  
  get请求测试用例 C:
  http://localhost:8080/test?addr=上海
  请求头:(无 content-type charset=utf-8;)/ content-type charset=iso-8859-1;
  server.xml配置<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
  服务端收到请求后的处理方式:同A
  结果:getParameter("addr") 解码正确
  
  参数解析过程(待整理):
  -> server.xml
Connector -> setURIEncoding
CoyoteAdapter -> server(req: org.apache.coyote.Request, res: org.apache.coyote.Response) ->
req.getParameters():org.apache.tomcat.util.http.Parameters.setQueryStringEncoding(connector.getURIEncoding()) ->
connector.getContainer().getPipeline().getFirst().invoke(request, response) -> doFilter ->
#? org.apache.catalina.connector.Request.setCharacterEncoding() -> org.apache.coyote.Request.setCharacterEncoding()
getParameters ->
enc = org.apache.coyote.Request.getCharacterEncoding() -> org.apache.coyote.Request.charEncoding -if null->get header content-type charset=???
-if enc != null->org.apache.tomcat.util.http.Parameters.setEncoding(enc)
--if connector.getUseBodyEncodingForURI() -> org.apache.tomcat.util.http.Parameters.setQueryStringEncoding(enc)
-else org.apache.tomcat.util.http.Parameters.setEncoding("iso-8859-1")
--if connector.getUseBodyEncodingForURI() -> org.apache.tomcat.util.http.Parameters.setQueryStringEncoding("iso-8859-1")
GET decode -> org.apache.tomcat.util.http.Parameters.handleQueryParameters() -> queryStringEncoding decode queryString
POST decode -> org.apache.tomcat.util.http.Parameters.processParameters -> encoding decode data
页: [1]
查看完整版本: Tomcat编码配置解疑