Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Javaservlet中从POST请求获取请求负载_Java_Http_Servlets_Post - Fatal编程技术网

在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

我有一个javascript库,它正在向我的Javaservlet发送POST请求,但是在
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
    with
    String::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);