先贴上代码
1.创建一个表单
// 创建一个表单
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
File photoFile = ResourceUtils.getFile("classpath:static/temp1.jpg");
builder.addTextBody("uid", uid");
builder.addTextBody("token", token);
builder.addBinaryBody("icon",photoFile);
String setIconUrl = "http://www.123.com";
JSONObject body = HttpClientUtil.httpYywSetIcon(setIconUrl, "utf-8", builder);
2.发送post请求
public static JSONObject httpYywSetIcon(String url, String encoding, MultipartEntityBuilder entityBuilder)
throws KeyManagementException, NoSuchAlgorithmException, ClientProtocolException, IOException {
// 采用绕过验证的方式处理https请求
SSLContext sslcontext = createIgnoreVerifySSL();
// 设置协议http和https对应的处理socket链接工厂的对象
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslcontext)).build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
HttpClients.custom().setConnectionManager(connManager);
// 创建自定义的httpclient对象
CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
// 定义数据分隔线
// String BOUNDARY = "========7d4a6d158c9";
// 创建post方式请求对象
HttpPost httpPost = new HttpPost(url);
// 构造消息头
// httpPost.setHeader("Content-type", "multipart/form-data; boundary=" + BOUNDARY);
httpPost.setHeader("Accept", "application/json");
//配置代理
RequestConfig requestConfig = RequestConfig.custom()
.setProxy(new HttpHost("localhost", 8888))
.build();
httpPost.setConfig(requestConfig);
// 设置参数到请求对象中
httpPost.setEntity(entityBuilder.build());
CloseableHttpResponse response = client.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
return new JSONObject();
}
//responseEntity才是真正收到的内容
HttpEntity responseEntity = response.getEntity();
String result = "";
if (responseEntity != null) {
result = EntityUtils.toString(responseEntity, "UTF-8");
}
EntityUtils.consume(responseEntity);
return JSONObject.parseObject(result);
}
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("SSLv3");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[] { trustManager }, null);
return sc;
}
如上的代码是可以实现表单上传的,但是也发现了一些问题,记录一下:
1 在 httpYywSetIcon 方法里有这2行代码
// 定义数据分隔线
String BOUNDARY = "========7d4a6d158c9";
// 构造消息头
httpPost.setHeader("Content-type", "multipart/form-data; boundary=" + BOUNDARY);
我刚开始只加了第二行,使用fiddler工具 查看表单内容是完全错乱的
后来加上BUUNDARY,发现表单里第一个key是正常的,其他是错乱的,所以是因为我的请求头数据分割的问题。
然后,我把这2行都注释了,发现正常了
2. 这只是HttpClient的用法,实际上使用流的 write方式,也可以实现这个功能,不过要加上数据分割线,数据传输开始和结束标志。