1

I have a JSP page(/Test/faces/pages/admin/csvImport.jsp) which has a form and a input file type File uploader. On clicking on Upload button the form gets submitted to self URL /Test/faces/pages/admin/csvImport.jsp and the files gets uploaded. I want to automate this file upload, and hence I am using HttpClient API to pick up the file and submit the form. I am trying upload a CSV file by POST request using HttpClient APIs but somehow the file is not getting uploaded. Here is the code snippet which does the upload:

        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);

The original HTML form which I want to simulate in java code is:

<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>

Can anyone give any hints why the file is not getting uploaded? When I execute the code, it just fetches the jsp page and does not upload the file.

UPDATE after comparing the HEADERS and POST PARAMETERS: Compared both the headers and parameters. With the FORM it is:

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

AND with HTTPClient it is:

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

The POST parameters with FORM:

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"

The POST parameters with HttpClient:

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=""
  • In browser while submitting use the developer tools to see the http post. In your application use a proxy (e.g.TCP/IP monitor in views in eclipse) to see the message being sent. Compare both and you will have your answer. – sashwat Apr 04 '16 at 08:45
  • I did the comparison, and I have added the results as an update above. No clue whatsoever, why its not working. – Vikas Kumar Apr 04 '16 at 12:23
  • Why is the content length different? Please try to compare post data also. Is this page secured? – sashwat Apr 05 '16 at 06:46
  • I referred http://stackoverflow.com/questions/8623870/how-can-i-programmatically-upload-a-file-to-a-website/8625286#8625286 and found that one POST parameter was wrongly named. After correcting the error, it started working in HTTP. But when I put the same code on HTTPS, it is still not submitting the form. I have added an additional hidden parameter javax.faces.ViewState. Is there something special we need to do when dealing with HTTPS? – Vikas Kumar Apr 05 '16 at 14:40
  • I have added headers for POST parameters for Secure call in the post. @sashwat, do you have any hints. The difference in length was because I was trying to upload different files. For HTTPS, the length is almost same. – Vikas Kumar Apr 05 '16 at 15:00

1 Answers1

0

Not sure it is the problem in your case, but MultipartEntityBuilder handles the Content-Type header and boundary internally so you do not have to set them explicitly. That is, you can safely remove the following lines

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

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

otherwise they might conflict each other.

Since you are just setting boundary to something random, you can just let MultipartEntityBuilder do it for you. This is the default behavior if you to not provide a boundary. And you can therefor also remove

    multipartEntity.setBoundary(boundary);
gustf
  • 1,959
  • 13
  • 20