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()这三种方法是有冲突的,因为流只能读取一次。

猜你喜欢

转载自blog.csdn.net/zxcc1314/article/details/82154361