在Javaservlet中从POST请求获取请求负载
我有一个javascript库,它正在向我的Javaservlet发送POST请求,但是在在Javaservlet中从POST请求获取请求负载,java,http,servlets,post,Java,Http,Servlets,Post,我有一个javascript库,它正在向我的Javaservlet发送POST请求,但是在doPost方法中,我似乎无法获取请求负载的内容。在chrome Developer Tools中,所有内容都在headers选项卡的Request Payload部分,内容就在那里,我知道doPost方法正在接收POST,但结果是空的 对于HttpServletRequest 对象,我可以通过什么方式获取请求负载中的数据 执行request.getParameter()或request.getAttrib
doPost
方法中,我似乎无法获取请求负载的内容。在chrome Developer Tools中,所有内容都在headers选项卡的Request Payload部分,内容就在那里,我知道doPost方法正在接收POST,但结果是空的
对于HttpServletRequest
对象,我可以通过什么方式获取请求负载中的数据
执行request.getParameter()
或request.getAttributes()
两者都没有数据简单回答:使用getReader()读取请求的正文 更多信息:
读取正文中的数据有两种方法:
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;
}
您可以从请求到读取使用缓冲区读取器
// 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()
Java8流
String body = request.getReader().lines()
.reduce("", (accumulator, actual) -> accumulator + actual);
有了它,你可以在一行中完成这项工作
IOUtils.toString(request.getReader())
你只需要
request.getParameterMap()
用于获取POST和GET参数
该方法返回一个映射
您可以通过以下方式读取地图中的参数:
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);
}
}
Map Map=request.getParameterMap();
//看地图
//适用于GET&POST方法
for(字符串paramName:map.keySet()){
字符串[]paramValues=map.get(paramName);
//获取参数名称的值
for(字符串值参数:参数值){
//输出值
System.out.println(“名为“+paramName+”:“+valueOfParam的参数值”);
}
}
使用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);
}
}
如果正文的内容是Java 8中的字符串,则可以执行以下操作:
String body=request.getReader().lines().collect(collector.joining());
如果您能够以JSON格式发送有效负载,这是读取播放负载最方便的方式:
示例数据类:
public class Person {
String firstName;
String lastName;
// Getters and setters ...
}
示例有效负载(请求主体):
在servlet中读取有效负载的代码(需要com.google.gson.*):
就这些。漂亮、简单、干净。不要忘记将内容类型头设置为application/json 您需要指定哪个参数,例如,如果正文中有关键字,请使用字符串keyword=request.getParameter(“关键字”);看到JavaScript代码发送请求会很有趣。显然,它以错误的方式组合了请求参数。@rash是的,我知道,我只是指定了我正在尝试的方法。BalusC我正在使用Resubable.js库来处理分割文件上载如果我没有弄错的话,在从输入流读取之前不要使用request.getParameter(),否则将没有可用的数据(已经读取)。没有问题,有点隐晦的是,如果你只是在一个过滤器中使用了这篇文章,然后发现没有其他东西可以再次读取正文,那么这篇文章可能会很有用@斯格特普基先生,我的好先生,请随意为这一评论添加一些理由@大卫·弗兰西斯我不是想在这里对你进行个人评价,但是:你没有提供任何背景。。没有文档链接,没有示例。您对我的评论的回复似乎比答案本身更需要努力。@SgtPooki是正确的,因为这些东西都不需要。所需方法的名称有些模糊,因此方法名称就是这个问题的答案。就像我想的那样简单。如果您认为有帮助,请随时提交更长的答案。请考虑到
request.getInputStream()
不像request.getReader()
那样接受请求字符编码。因此,本例使用默认的系统字符集。new BufferedReader(new InputStreamReader(request.getInputStream())
可以简化为request.getReader()
已缓冲并保留请求编码。我发现此解决方案很有用,因为引发了一个异常:javax.servlet.ServletException:java.lang.IllegalStateException:getInputStream()已为此请求调用。
当我调用getReader()时,由于阅读器已经打开。谢谢先生,这是一个简洁明了的解决方案!这很有趣,但在字符串连接方面看起来效率很低!有什么方法可以改进吗?String body=request.getReader().lines().collect(Collectors.joining());也可能有效。Collectors.joining显然使用了StringBuilder。我认为它应该请求.getReader().lines().collect(joining(“\n”))来保留换行符。在java 8中,流将被并行处理,因此需要添加sequential方法,否则它将合并数据的错误部分-String body=request.getReader().lines().sequential().reduce(System.lineSeparator(),(累加器,实际)->累加器+实际)您可以替换(累加器,实际)->acculator+actual
withString::concat
。注意:参数仅在使用编码应用程序/x-www-form-urlencoded
时可用;对于多部分/表单数据
,显然需要通过请求访问主体部分。getReader()
并手动解析。这在我必须实现JWT身份验证的情况下有效。我发送带有用户名和密码的JSON负载,然后将其映射到我的自定义身份验证令牌类。
public class Person {
String firstName;
String lastName;
// Getters and setters ...
}
{ "firstName" : "John", "lastName" : "Doe" }
Person person = new Gson().fromJson(request.getReader(), Person.class);