今天帮小伙伴解决了一个请求参数乱码问题,大概花费2个小时吧,要不是前段时间自己稍微花时间看了看spring mvc框架的源码,估计今天要花好长时间解决这个问题了。起先我让小伙伴试试利用tomcat源码来进行调试一下,小伙伴感觉有些吃力,就交给我帮忙解决一下,还好帮他搞定了这个问题。
tomcat的参数解析涉及到如下几个类:
org.apache.coyote.Request
低级别类,用于包装socket的请求了。
org.apache.tomcat.util.http.Parameters
集中存放解析的参数,post请求参数个get请求的参数
org.apache.catalina.connector.RequestFacade
请求门面,包装请求,是请求的实现类,但其实是谁的门面呢?是coyoteRequest,
springmvc框架会调用request的getParameterValues方法,而这个方法又调用实际的coyoteRequest的getParameterValues方法,这个方法会首先判断以前是否已经解析过参数了,如果没有解析参数,那么就发生第一次解析参数的操作。
调用parseParameters方法解析所有的参数,包括url的参数,这个函数里面,会调用Rquest类的getParameters方法,你敢相信,每当来一个请求,就创建一个Request对象,我们的参数就预先创建放到Request对象里面了。
获得Parameters对象,则要解析url里面的参数,还要解析请求体里面的参数。一个参数一个参数地解析,每解析一个就存放到paramHashValues对象里面。这个对象是个HashMap对象。
小伙伴出现乱码的原因就是Filter放置的顺序有些问题,设置编码的Filter应该放置在第一个位置,首先进行配置编码,而小伙伴的这个Filter放在了一个XSS处理的Filter的后面,可想而知,XSS提前进行了参数解析,没有使用UTF-8编码,然后缓存了起来,后续设置编码的Filter没有起到任何作用,从而发生了乱码问题。
网络程序真是io密集型的啊,解析参数并非简简单单,基本上就是从socket里面取数据,都是一个字节一个字节的解析的。具体的参数格式啥的,我们就不深究了,感觉没有必要啊,到时候有时间再进行集中式的回顾学习,加深对java web程序的理解和掌握。
感觉针对我们开发常用的开发框架,还是要稍微了解点源码,否则,面对陌生的源码环境,感觉未必能在非常短的时间内解决问题啊。