Java http post 用于多部分数据
Java http post for multipart data
我正在使用 Apache HttpComponents v4.3.6(maven httpclient 和 httpmime)。我需要将文件数据作为多部分上传。有效的 Fiddler 命令如下所示。
在 Fiddler 上请求 header:
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
在 Fiddler 上请求 body:
--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--
文件的实际内容是:
585743 583099 Existing Catrali 4Category ch Description of 4 Existing Category false false false Some notes 4 relating to Existing Category
现在,我正在尝试使用 Apache Http Client 实现此 post 请求(如上所述),但不知道如何实际执行。要将上述请求转换为 Java (1.8),我尝试了: ( 边界值: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() );
我确定我在 Java 中制作 request-body 的方式是错误的。 因此,我看到 403 错误,这是一种误导因为我正在调用的 REST api 在没有看到预期的 format.I 时抛出此错误,将不胜感激。
提前致谢。
因为我从 fiddler 那里获得了成功的交易,所以我将 fiddler 与 eclipse 集成在一起,以找出 api 通过 java 代码调用所造成的差异。最后,使用此代码成功:
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;
}
我正在使用 Apache HttpComponents v4.3.6(maven httpclient 和 httpmime)。我需要将文件数据作为多部分上传。有效的 Fiddler 命令如下所示。
在 Fiddler 上请求 header:
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
在 Fiddler 上请求 body:
--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--
文件的实际内容是:
585743 583099 Existing Catrali 4Category ch Description of 4 Existing Category false false false Some notes 4 relating to Existing Category
现在,我正在尝试使用 Apache Http Client 实现此 post 请求(如上所述),但不知道如何实际执行。要将上述请求转换为 Java (1.8),我尝试了: ( 边界值: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() );
我确定我在 Java 中制作 request-body 的方式是错误的。 因此,我看到 403 错误,这是一种误导因为我正在调用的 REST api 在没有看到预期的 format.I 时抛出此错误,将不胜感激。
提前致谢。
因为我从 fiddler 那里获得了成功的交易,所以我将 fiddler 与 eclipse 集成在一起,以找出 api 通过 java 代码调用所造成的差异。最后,使用此代码成功:
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;
}