HttpServletRequest.getParameter()源码分析
HttpServletRequest.getParameter(); debug看到HttpServletRequest这个类的实例其实是RequestFacade。 到tomcat源码中可以看到该类。 RequestFacade外观模式实现,包装了Request。 RequestFacade.getParameter(String name),该方法调用了Request的方法。 org.apache.catalina.connector.Request.getParameter(String name), 该方法调用了parseParameters()。
/**
* Parse request parameters.
*/
protected void parseParameters() {
parametersParsed = true;
//解析的body封装在Parameters类中,coyoteRequest(org.apache.coyote.Request)封装了Parameters
Parameters parameters = coyoteRequest.getParameters();
boolean success = false;
try {
/**
* 省略。。。
* 处理报文头,在此之前报文头已解析完成
* */
//读取body放到formData中,formData为byte数组
if (readPostBody(formData, len) != len) {
parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE);
return;
}
//省略。。。
//处理解析body
parameters.processParameters(formData, 0, len);
//省略。。。
}
}
org.apache.tomcat.util.http.Parameters.processParameters()主要就是通过while循环解析formData byte数组。并且把结果以key-value的形式放再Map中。
while(pos < end) {
//省略...
switch(bytes[pos]) {
case =:
//省略...
break;
case &:
//省略...
break;
case %:
case +:
//省略...
break;
default:
pos ++;
break;
}
//省略...
}
所以Servlet其实在doPost,doGet之前已经解析完毕http协议的请求行和请求头。 并且request.getParameter(),request.getInputStream(),request.getReader()这三种方法是有冲突的,因为流只能读取一次。
