【问题标题】:Not able to upload file using HttpClient POST request无法使用 HttpClient POST 请求上传文件
【发布时间】:2016-04-04 08:33:56
【问题描述】:

我有一个 JSP 页面(/Test/faces/pages/admin/csvImport.jsp),它有一个表单和一个输入文件类型文件上传器。单击“上传”按钮后,表单将提交到自己的 URL /Test/faces/pages/admin/csvImport.jsp 并上传文件。我想自动上传这个文件,因此我使用 HttpClient API 来获取文件并提交表单。我正在尝试使用 HttpClient API 通过 POST 请求上传 CSV 文件,但不知何故该文件没有上传。这是上传的代码sn-p:

        HttpContext localContext = new BasicHttpContext();
        localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);

        HttpPost httpPost = new HttpPost("http://localhost:9088/Test/faces/pages/admin/csvImport.jsp");
        httpPost.setHeader("Cookie", "JSESSIONID="+ sessionId);
        String boundary = "---------------------------" + System.currentTimeMillis();

        httpPost.setHeader("Content-Type", "multipart/form-data; boundary="+boundary);
        
        File file = new File("C:\\root\\projects\\DataSources1.csv");
        FileBody fileBody = new FileBody(file); 
        StringBody importBody = new StringBody("Import", ContentType.TEXT_PLAIN);
        StringBody csvImportFormBody = new StringBody("csvImportForm", ContentType.TEXT_PLAIN);
        StringBody uniqueTokenBody = new StringBody("j911", ContentType.TEXT_PLAIN);
        StringBody uniqueViewBody = new StringBody("j911", ContentType.TEXT_PLAIN);

        MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();

        multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        multipartEntity.setBoundary(boundary);
        multipartEntity.addPart("uploadFileName", fileBody);
        multipartEntity.addPart("csvimportForm:ImportButton", importBody);
        multipartEntity.addPart("csvImportForm", csvImportFormBody);
        multipartEntity.addPart("uniqueToken", uniqueTokenBody);
        multipartEntity.addPart("uniqueView", uniqueViewBody);

        httpPost.setEntity(multipartEntity.build());
        HttpResponse response = httpClient.execute(httpPost,localContext);

我想用java代码模拟的原始HTML表单是:

<form id="csvImportForm" method="post" action="/Test/faces/pages/admin/csvImport.jsp" enctype="multipart/form-data">
    <tr>
        <td width="25%" class="trayheader">
            <!-- "File Name" (label) --> <span id="csvImportForm:fileNameTitleId">File Name:</span></td>
        <td width="50%">
            <!-- File Selection (input) --> <input type="file" name="uploadFileName" style="width: 90%"></td>
        <td width="25%">
            <!-- Import (button) --> <input type="submit" value="Import" name="csvImportForm:importButton" id="csvImportForm:importButton" onclick="javascript:hideForm();" class="commandExButton" /></td>
    </tr>
    <input type="hidden" name="csvImportForm" value="csvImportForm" /><input type="hidden" name="csvImportForm:_idcl" /><input type="hidden" name="clickedLogoutLink" />
</form>

任何人都可以提供任何提示,为什么文件没有被上传?当我执行代码时,它只是获取jsp页面而不上传文件。

比较 HEADERS 和 POST PARAMETERS 后的更新: 比较了标头和参数。 使用 FORM 是:

Request               POST /Test/faces/pages/admin/csvImport.jsp HTTP/1.1
Accept  */*
Referer                https://host1:30862/Test/faces/pages/admin/csvImport.jsp
Accept-Language             en-GB
User-Agent         Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Content-Type    multipart/form-data; boundary=---------------------------7e0212b90428
Accept-Encoding              gzip, deflate
Host       host1:30862
Content-Length                2398
DNT       1
Connection        Keep-Alive
Cache-Control   no-cache
Cookie  ssoLang=en; dbihybrid_preferredLanguage=en; dbihybrid_locationDepartment=in.false; wt_eid=2143773288100110717; JSESSIONID=W9vmLJRZkf7u2Pevmd4QdSC2hUvliVepaVm-tFuz9m7O4lkWYPUw!1008091679; PA.MinLogLevel=30

与 HTTPClient 是:

Cookie: JSESSIONID=9C_m5OE8QUquA9sdj4T5eOyVS1yXC6yb0jdiVCuaZ_X-MjPQqEMw!1008091679
Content-Type: multipart/form-data; boundary=---------------------------1459867674444
Accept-Language: en-US,en;q=0.5
Accept: */*
Cache-Control: no-cache
Referrer: https://host1:30862/Test/faces/pages/admin/csvImport.jsp
Content-Length: 2423
Host: host1:30862
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.3.1 (java 1.5)
Accept-Encoding: gzip,deflate

带有FORM的POST参数:

Content-Disposition: form-data; name="csvImportForm" value="csvImportForm"
Content-Disposition: form-data; name="uniqueToken" value=""
Content-Disposition: form-data; name="uniqueView" value="j1154"
Content-Disposition: form-data; name="csvImportForm:importStatus" value=""
Content-Disposition: form-data; name="clipboard_l" value=""
Content-Disposition: form-data; name="clipboard_t" value=""
Content-Disposition: form-data; name="uploadFileName"; filename="C:\Users\Public\Documents\eclipse luna\workspace\WebScraper\properties\DataSources.csv" Content-Type: application/vnd.ms-excel
Content-Disposition: form-data; name="csvImportForm:importButton" value="Import"
Content-Disposition: form-data; name="javax.faces.ViewState" value="3514046226787645214:-6068281828613739341"

HttpClient的POST参数:

Content-Disposition: form-data; name="uploadFileName"; filename="C:\Users\Public\Documents\eclipse luna\workspace\WebScraper\properties\DataSources.csv" Content-Type: application/vnd.ms-excel; charset=UTF-8
Content-Disposition: form-data; name="csvImportForm:importButton" value="Import"
Content-Disposition: form-data; name="csvImportForm" value="csvImportForm"
Content-Disposition: form-data; name="uniqueToken" value="j1228"
Content-Disposition: form-data; name="uniqueView" value="j1228"
Content-Disposition: form-data; name="javax.faces.ViewState" value="8959970480121731339:-7418251671370896640"
Content-Disposition: form-data; name="clipboard_l" value=""
Content-Disposition: form-data; name="clipboard_t" value=""
Content-Disposition: form-data; name="csvImportForm:importStatus" value=""

【问题讨论】:

  • 在浏览器中提交时使用开发者工具查看 http 帖子。在您的应用程序中使用代理(例如 Eclipse 中的视图中的 TCP/IP 监视器)来查看正在发送的消息。比较两者,你就会得到答案。
  • 我进行了比较,并将结果添加为上面的更新。没有任何线索,为什么它不起作用。
  • 为什么内容长度不同?请尝试比较帖子数据。此页面是否安全?
  • 我参考了stackoverflow.com/questions/8623870/…,发现有一个POST参数被错误命名。更正错误后,它开始在 HTTP 中工作。但是当我将相同的代码放在 HTTPS 上时,它仍然没有提交表单。我添加了一个额外的隐藏参数 javax.faces.ViewState。在处理 HTTPS 时,我们需要做些什么特别的事情吗?
  • 我在帖子中添加了用于安全调用的 POST 参数的标题。 @sashwat,你有什么提示吗?长度的差异是因为我试图上传不同的文件。对于 HTTPS,长度几乎相同。

标签: java http post file-upload httpclient


【解决方案1】:

不确定这是您的问题,但MultipartEntityBuilder 在内部处理 Content-Type 标头和边界,因此您不必显式设置它们。也就是说,您可以安全地删除以下行

    String boundary = "---------------------------" + System.currentTimeMillis();

    httpPost.setHeader("Content-Type", "multipart/form-data; boundary="+boundary);

否则它们可能会相互冲突。

由于您只是将边界设置为随机的,您可以让MultipartEntityBuilder 为您做这件事。如果您不提供边界,这是默认行为。因此,您也可以删除

    multipartEntity.setBoundary(boundary);

【讨论】:

  • 我删除了它,但这并没有帮助。感谢您的回复。
猜你喜欢
  • 2019-12-11
  • 1970-01-01
  • 2018-12-16
  • 2021-08-10
  • 1970-01-01
  • 2022-10-09
  • 2014-10-10
  • 2018-06-08
  • 2021-12-19
相关资源
最近更新 更多