HttpServletRequest#getParameter

以Tomcat容器实现为例

实现类为org.apache.catalina.connector.Request

关键代码

1
2
3
4
5
6
7
8
@Override
public String getParameter(String name) {
// 确保一个Request只会执行一次解析
if (!parametersParsed) {
parseParameters();
}
····
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
protected void parseParameters() {
try {
// 处理URL拼接的请求参数
parameters.handleQueryParameters();

if (usingInputStream || usingReader) {
success = true;
return;
}
// 获取ContentType 如果有多个取第一个为准
String contentType = getContentType();
if (contentType == null) {
contentType = "";
}
int semicolon = contentType.indexOf(';');
if (semicolon >= 0) {
contentType = contentType.substring(0, semicolon).trim();
} else {
contentType = contentType.trim();
}
// 判断ContentType类型 如果是多媒体类型 那么使用ParseParts
if ("multipart/form-data".equals(contentType)) {
parseParts(false);
success = true;
return;
}
// 判断是否是需要解析请求体的请求 POST
if( !getConnector().isParseBodyMethod(getMethod()) ) {
success = true;
return;
}
// 当contenttype不为application/x-www-form-urlencoded退出,不在执行下面的关键代码
if (!("application/x-www-form-urlencoded".equals(contentType))) {
success = true;
return;
}

int len = getContentLength();

if (len > 0) {
int maxPostSize = connector.getMaxPostSize();
if ((maxPostSize >= 0) && (len > maxPostSize)) {
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
context.getLogger().debug(
sm.getString("coyoteRequest.postTooLarge"));
}
checkSwallowInput();
parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
return;
}
byte[] formData = null;
if (len < CACHED_POST_LEN) {
if (postData == null) {
postData = new byte[CACHED_POST_LEN];
}
formData = postData;
} else {
formData = new byte[len];
}
try {
// readPostBody方法其实就是request.getinputstream().read(); 所以getParameter会读取完流,如果需要流多次读取那么需要使用包装类
if (readPostBody(formData, len) != len) {
parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE);
return;
}
} catch (IOException e) {
// Client disconnect
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
context.getLogger().debug(
sm.getString("coyoteRequest.parseParameters"), e);
}
parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
return;
}
parameters.processParameters(formData, 0, len);
} else if ("chunked".equalsIgnoreCase(
coyoteRequest.getHeader("transfer-encoding"))) {
byte[] formData = null;
try {
formData = readChunkedPostBody();
} catch (IllegalStateException ise) {
// chunkedPostTooLarge error
parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
context.getLogger().debug(
sm.getString("coyoteRequest.parseParameters"),
ise);
}
return;
} catch (IOException e) {
// Client disconnect
parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
Context context = getContext();
if (context != null && context.getLogger().isDebugEnabled()) {
context.getLogger().debug(
sm.getString("coyoteRequest.parseParameters"), e);
}
return;
}
if (formData != null) {
parameters.processParameters(formData, 0, formData.length);
}
}
success = true;
} finally {
if (!success) {
parameters.setParseFailedReason(FailReason.UNKNOWN);
}
}
}