Search code examples
javahttppostmultipartform-datamultipart

Java http post for multipart data


I am using Apache HttpComponents v4.3.6 (maven httpclient and httpmime). I need to upload a file data as multipart. The Fiddler command, which works, looks like the following.

Request header on Fiddler:

Content-Type: multipart/form-data; boundary=c2d7073062e24d86ad739647574e14b9
Accept: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0

Request body on Fiddler:

--c2d7073062e24d86ad739647574e14b9
Content-Disposition: form-data; name="categoryFile"; filename="self-classification-categories.tsv"

585743  583099  Existing Catrali 4Category ch   Description of 4 Existing Category  false   false   false   Some notes 4 relating to Existing Category
--c2d7073062e24d86ad739647574e14b9--

Where the actual content of the file is :

585743  583099  Existing Catrali 4Category ch   Description of 4 Existing Category  false   false   false   Some notes 4 relating to Existing Category

Now, I'm trying to implement this post request(described above) with Apache Http Client, but have no idea how to actually do it. To convert the above request into Java (1.8), I tried: ( Boundary value : c2d7073062e24d86ad739647574e14b9)

httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost( createPostURI( host, path ) );

httpPost.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0");
httpPost.setHeader("Content-Type", "multipart/form-data; boundary=c2d7073062e24d86ad739647574e14b9");
httpPost.setHeader("Accept", "application/json");


String fileContent = "--c2d7073062e24d86ad739647574e14b9\r\nContent-Disposition: form-data; name=\"categoryFile\"; filename=\"self-classification-categories.tsv\""+
                "\r\n\r\n"+
                "585743 583099  Existing Catrali 4Category ch   Description of 4 Existing Category  false   false   false   Some notes 4 relating to Existing Category"
                +"\r\n--c2d7073062e24d86ad739647574e14b9--";

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setBoundary("c2d7073062e24d86ad739647574e14b9");
builder.addTextBody("body", fileContent,ContentType.MULTIPART_FORM_DATA);

HttpEntity entity =  builder.build();
httpPost.setEntity( entity );

response = httpclient.execute( httpPost, new GenericResponseHandler() );

I am sure that the way I am crafting the request-body in Java is wrong. Hence, I seeing 403 error which is kind of misleading as the REST api that I am calling throws this error when it does not see the expected format.I would appreciate any help.

Thanks in advance.


Solution

  • As I had successful transactions from fiddler,I integrated fiddler with eclipse to figure out the differences made by the api-calls through java code. And finally, was successful with this code:

    public GenericResponse processHttpPostRequest( String host, String path,String content, Map<String, String> parameters, String multiPartDataBounadry ,String outfilePath)
    {
        CloseableHttpClient httpclient = null;
    
        GenericResponse response = null;
        try
        {
            //This is important to integrate eclipse with fiddler
            HttpHost proxy = new HttpHost("localhost", 8888);
    
            HttpPost httpPost = new HttpPost( createPostURI( host, path,parameters) );
    
    
            setHeader(multiPartDataBounadry, httpPost);
    
            //This is important to integrate eclipse with fiddler
            httpclient = HttpClients.custom().setProxy(proxy).disableContentCompression().build(); 
            //httpclient = HttpClients.createDefault();
    
            HttpEntity entity = setRequestBody(content, multiPartDataBounadry);
    
            httpPost.setEntity( entity );
    
            LOGGER.info( "Executing request URI " + httpPost.getURI() );
    
            response = httpclient.execute( httpPost, new GenericResponseHandler() );
            handleResponse(response, outfilePath);
    
            if (response.getStatusCd() != 200)
            {
                handleResponseError(parameters, response);
            }
    
        }
        catch(Throwable e)
        {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    
        finally
        {
            closeClient(httpclient);
        }
    
        return response;
    }
    
    private void setHeader(String multiPartDataBounadry, HttpEntityEnclosingRequestBase httpEntity) 
    {
        httpEntity.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:22.0) Gecko/20100101 Firefox/22.0");
        httpEntity.setHeader("Content-Type", "multipart/form-data; boundary="+multiPartDataBounadry);
        httpEntity.setHeader("Accept", "application/json");
    }
    
    private HttpEntity setRequestBody(String content, String multiPartDataBounadry) 
    {
        FormBodyPart bodyPart = FormBodyPartBuilder.create()                    
                .setName("any_name")
                .addField("Content-Disposition", "form-data; name=\"categoryFile\"; filename=\"self-classification-categories.tsv\"")
                .setBody(new StringBody(content, ContentType.MULTIPART_FORM_DATA))
                .build();
    
        MultipartEntityBuilder builder = MultipartEntityBuilder.create()
                .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .setBoundary(multiPartDataBounadry)
                .addPart(bodyPart);
    
        HttpEntity entity =   builder.build();
    
        return entity;
    
    }
    
    
    private URI createPostURI( String host, String path , Map<String, String> parameters) throws Exception
    {
        URI finalURL = null;
        try
        {
            URIBuilder url = null;
            url = new URIBuilder();
            url.setScheme( "http" );
            url.setHost( host );
            url.setPath( path );
            url.setParameter("first_param", "first_param_value");
            url.setParameter("second_param","second_param_value");
    
            finalURL =  url.build() ;
    
        }
        catch ( URISyntaxException |  IllegalArgumentException  e )
        {
            e.printStackTrace();
            throw e;
        }
    
        return finalURL;
    }