我有一个JavaScript库,它正在向我的Java servlet发送POST请求,但在doPost
方法中,我似乎无法获取请求负载的内容。在Chrome开发者工具中,所有内容都在标题选项卡的请求负载部分中,内容都在那里,我知道POST已被doPost
方法接收,但它只是空白。
对于HttpServletRequest
对象,我该如何获取请求负载中的数据?
public class TestFilter implements Filter {
我有一个JavaScript库,它正在向我的Java servlet发送POST请求,但在doPost
方法中,我似乎无法获取请求负载的内容。在Chrome开发者工具中,所有内容都在标题选项卡的请求负载部分中,内容都在那里,我知道POST已被doPost
方法接收,但它只是空白。
对于HttpServletRequest
对象,我该如何获取请求负载中的数据?
public class TestFilter implements Filter {
简单回答:
使用getReader()来读取请求体
更多信息:
有两种方法可以读取请求体:
getReader()
返回一个BufferedReader,它允许您读取请求体。
getInputStream()
如果需要读取二进制数据则返回一个ServletInputStream。
文档中的注意事项:"[两种方法] 都可以用来读取请求体,但不要同时使用。"
String payloadRequest = getBody(request);
使用此方法
public static String getBody(HttpServletRequest request) throws IOException {
String body = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
return body;
}
request.getInputStream()
不像 request.getReader()
一样遵循请求字符编码。因此,此示例使用默认系统字符集。 - Vadzimnew BufferedReader(new InputStreamReader(request.getInputStream()))
可以简化为 request.getReader()
,后者已经缓冲且保留了请求编码。 - Vadzimjavax.servlet.ServletException: java.lang.IllegalStateException: getInputStream() has already been called for this request
异常。我发现这个解决方案很有帮助。 - Benjamin Slabbert // Read from request
StringBuilder buffer = new StringBuilder();
BufferedReader reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
buffer.append(System.lineSeparator());
}
String data = buffer.toString()
Java 8流
String body = request.getReader().lines()
.reduce("", (accumulator, actual) -> accumulator + actual);
String::concat
替换(accumulator, actual) -> accumulator + actual
。 - shmosel如果Java 8中请求正文内容是字符串,可以这样操作:
String body = request.getReader().lines().collect(Collectors.joining());
public class Person {
String firstName;
String lastName;
// Getters and setters ...
}
示例负载(请求正文):
{ "firstName" : "John", "lastName" : "Doe" }
读取Servlet中的有效载荷代码(需要com.google.gson.*):
Person person = new Gson().fromJson(request.getReader(), Person.class);
就是这样。简单易懂且干净利落。不要忘记将 content-type 标头设置为 application/json。
使用Java 8的资源管理器:
StringBuilder stringBuilder = new StringBuilder();
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
char[] charBuffer = new char[1024];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
}
request.getParameterMap()
用于获取POST和GET参数。
该方法返回一个Map<String,String[]>
。
您可以通过此Map读取参数。
Map<String, String[]> map = request.getParameterMap();
//Reading the Map
//Works for GET && POST Method
for(String paramName:map.keySet()) {
String[] paramValues = map.get(paramName);
//Get Values of Param Name
for(String valueOfParam:paramValues) {
//Output the Values
System.out.println("Value of Param with Name "+paramName+": "+valueOfParam);
}
}
application/x-www-form-urlencoded
时才可用;如果使用 multipart/form-data
,则需要通过 request.getReader()
访问请求正文并手动解析它。 - twonkeys