【问题标题】:Sending multiple files in one post Request in HttpURLConnection in JAVAJAVA中HttpURLConnection中的一个帖子请求中发送多个文件
【发布时间】:2016-06-29 00:23:41
【问题描述】:

我正在使用 HttpURLConnection 通过 post 方法发送文件。我正在向文件发送一个“student_id”参数。在每个发布请求中发送一个文件时,该代码工作正常。 但是,我如何更新下面的代码以在一个帖子请求中发送多个文件,其中所有文件都属于同一个“student_id”

       try{  
            File textFile2 = new File("info.txt");  

         URL url = new URL("htttp://wwww.students.com");
         HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();         
         urlConnection.setChunkedStreamingMode(0);
         urlConnection.setDoOutput(true);   


        String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.

        urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);          
        OutputStream output = urlConnection.getOutputStream();
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);

        writer.append("--" + boundary).append(CRLF);
        writer.append("Content-Disposition: form-data; name=\"student_id\"").append(CRLF);
        writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
        writer.append(CRLF).append("25").append(CRLF).flush();


        writer.append("--" + boundary).append(CRLF);
        writer.append("Content-Disposition: form-data; name=\"newfile\"; filename=\"" + textFile2.getName() + "\"").append(CRLF);
        writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
        writer.append(CRLF).flush();                                                            
        Files.copy(textFile2.toPath(), output);//copies all bytes in  a file to the output stream 
        output.flush(); // Important before continuing with writer!
        writer.append(CRLF).flush();

        writer.append("--" + boundary + "--").append(CRLF).flush();
        InputStream responseStream; 

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }

我尝试在“newfile”中使用参数添加“multiple”,但它不起作用

        writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"newfile\" multiple; filename=\"" + textFile2.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();                                                            
    Files.copy(textFile2.toPath(), output);//copies all bytes in  a file to the output stream 
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush();

    writer.append("--" + boundary + "--").append(CRLF).flush();

【问题讨论】:

  • 将 OutputStream 的包装器与对原始 OutputStream 的直接写入混合在一起会产生问题。使用 PrintStream 而不是 PrintWriter,并将该 PrintStream 传递给 Files.copy。一旦将 OutputStream 包装在 PrintStream 或 OutputStreamWriter 之类的东西中,就不应再次引用该 OutputStream。
  • 如果可能的话,你能给我举个例子来说明你的建议吗
  • PrintWriter writer = … 更改为PrintStream writer = new PrintStream(output, true, charset);。将 Files.copy 语句更改为 Files.copy(textFile2.toPath(), writer);。这样,所有行都写入完全相同的输出对象。删除对 output.flush() 的调用。记得打电话给writer.close()

标签: java file post httpurlconnection


【解决方案1】:

您似乎正在尝试发布带有 1 个 表单字段multipart/form-data 请求,其中 name 参数为 student_id 和多个 文件部分 以上传文件。

您可以通过在单独的部分中提供每个文件来发送多个文件,但所有文件都具有相同的name 参数。

例如,您可以通过发送带有name参数newfile的第一个文件部分来上传textFile1的文件:

writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"newfile\"; filename=\"" + textFile1.getName()+ "\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF);
writer.flush();

FileInputStream inputStream = new FileInputStream(textFile1);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();

writer.append(CRLF);
writer.flush();

然后,您可以通过发送与newfile 相同的name 参数的文件部分来上传textFile2 的另一个文件:

writer.append("--" + boundary).append(CRLF);
writer.append("Content-Disposition: form-data; name=\"newfile\"; filename=\"" + textFile2.getName()+ "\"").append(CRLF);
writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
writer.append("Content-Transfer-Encoding: binary").append(CRLF);
writer.append(CRLF);
writer.flush();

FileInputStream inputStream = new FileInputStream(textFile2);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
    outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();

writer.append(CRLF);
writer.flush();

如您所见,除了要上传的文件外,代码几乎相同。建议将代码放入一个方法中并调用它来发送每个文件部分

【讨论】:

  • 我正在尝试使用名为 student_id 的 2 个表单字段发送到 post multipart/form-data 请求,第二个字段是保存文件的“newfile”。因此,我无法更改表单中的名称字段“newfile”
  • @ryh12 我用例子更新了它。请看看有没有帮助
  • 我试过你的方法,但它只添加第一个文件而忽略了另一个文件@Wilson
  • @ry12 如果服务器端支持为一个带有分隔文件部分的表单字段上传多个文件,它应该可以工作。我怀疑服务器端使用较旧的方法来解析带有嵌套“多部分/混合”部分的请求,或者它不支持为一个表单字段上传多个文件。服务器端是你实现的吗?你知道服务器端支持什么方法吗?
猜你喜欢
  • 2017-01-25
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多