看到有人直接通过ServletRequest.getInputStream()中读取Post中的body,代码大概如下:
String charset = request.getCharacterEncoding();
if (charset == null) {
charset = DEFAULT_ENCODE;
}
BufferedReader in = new BufferedReader(new InputStreamReader(request
.getInputStream(), charset));
// Read the request
CharArrayWriter data = new CharArrayWriter();
char[] buf = new char[8192];
int ret;
while ((ret = in.read(buf, 0, 8192)) != -1) {
data.write(buf, 0, ret);
}
return data.toString();
当时心里有个疑问:为什么不直接通过调用request.getParameter()来获取相应的值呢?虽然至今也没想到答案,但是通过查看servlet规范了解到了ServletRequest的一个小知识,规范原文如下:
SRV.3.1.1 When Parameters Are Available The following are the conditions that must be met before post form data will be populated to the parameter set: 1. The request is an HTTP or HTTPS request. 2. The HTTP method is POST. 3. The content type is application/x-www-form-urlencoded. 4. The servlet has made an initial call of any of the getParameter family of methods on the request object. If the conditions are not met and the post form data is not included in the parameter set, the post data must still be available to the servlet via the request object’s input stream. If the conditions are met, post form data will no longer be available for reading directly from the request object’s input stream.
英文比较简单,就不翻译了。
补充:对之前问题“为什么不直接通过调用request.getParameter()来获取相应的值呢”的解答
不使用request.getParameter()来获取,而是在自己业务逻辑代码中处理有以下几种可能:
1、request的body内容不是“参数名=参数值”的形式,而单纯是一段文字或者二进制字节流,这样就不可能通过request.getParameter()来获取参数值;
2、如果request的body内容的格式是固定的,那么在程序代码中可以针对这种特定的格式进行优化处理;
3、如果request的body内容比较长,并且网络环境又不好,那么直接调用request.getParameter()将会阻塞较长时间。并且如果body的内容允许边接受边处理的话(比如xml),那么通过自己的业务逻辑代码来处理body内容效率将会更高;
以上答案仅仅是本人的理解,仅供参考。