Web容器自己主动对HTTP请求中參数进行URLDecode处理
如题。在Java中或许非常多人都没有注意到当我们发送一个http请求给时,假设附带的參数被URLEncode之后,到达web容器之后,开发人员获取到的參数值会自己主动变成了encode之前的值。这是一个非常好的特点。开发人员全然能够忽略http的參数是否须要decode这样的事。可是decode究竟是在什么发生的呢?
一时兴起就陷了进去,于是就開始一层层的找起了。
第一步就是从request.getParameter()方法下手,可是ServletRequest仅仅是一个接口。是J2EE定义的Servlet框架的一个基本接口,详细实现还是得看详细的Servlet容器。即Web容器,我用的是JBOSS。所以就从JBOSS中源代码着手。同一时候为了找出当我们调用request.getParameter()时详细是调用哪个ServletRequest对象的方法,使用了反射来查找,代码例如以下:
System.out.println(request.getClass().getName());非常easy,通过request的getClass获取对象的详细名称,得到的结果是:org.apache.catalina.connector.RequestFacade。可见是Web容器提供的详细ServletRequest实现类。既然找到了详细的类接下来肯定是去看下API文档,看看有没有提到会对request參数值进行decode操作。顺便说下org.apache.catalina.connector.RequestFacade时Tomcat的API,果然文档并未提到不论什么关于decode的内容,反倒看到RequestFacade不过一个包装器,真正工作的居然另有其人。好吧,只能找到代码了。
找到RequestFacade的源代码,发现真正用于获取request參数的类是RequestFacade的一个受保护的变量request,当然这个类也是实现了ServletRequest接口的。继续查看Request源代码,发现真正干活的类还不是它,Request内部另一个变量org.apache.coyote.Request.coyoteRequest,继续找到org.apache.coyote.Request源代码。找到org.apache.coyote.Request源代码大致就已经能够看出究竟是什么时候进行的decode操作了。在org.apache.coyote.Request的构造器中能够看见:
public Request() { this.parameters.setQuery(this.queryMB); this.parameters.setURLDecoder(this.urlDecoder); this.parameters.setHeaders(this.headers); this.methodMB.setString("GET"); this.uriMB.setString("/"); this.queryMB.setString(""); this.protoMB.setString("HTTP/1.0"); }当中一句this.parameters.setURLDecoder(this.urlDecoder);指定了URLDecoder工具类,再来看看parameters能够看到该类就是用来解析http请求參数的类。该类会使用URLDecoder工具类对请求的name以及value进行decode操作。到这里基本就已经看到了HTTP请求中的參数究竟是怎样被自己主动decode的了。当中并没有去深究代码步骤。毕竟我们仅仅要知道是什么进行的decode就可以。
从上面的整个流程能够看出,对HTTP參数进行自己主动decode是Web容器依赖的,即并不是J2EE标准,所以其它Web容器有可能并未做这样的操作,所以开发人员还是得注意。