apache下的httpclient工具可大大簡化開發(fā)過程中的點對點通信螃征,本人將以微信多媒體接口為例,展示httpclient多媒體的上傳下載,本示例基于httpclient4.5道批。
- 上傳多媒體文件函數(shù)
/**
* HttpClient POST請求 ,上傳多媒體文件
*
* @param url 請求地址
* @param filePath 多媒體文件絕對路徑
* @return 多媒體文件ID
* @throws UnsupportedEncodingException
* @author Jie
* @date 2015-2-12
*/
@SuppressWarnings("resource")
public static String postForUploadStream(String url, String filePath) throws IOException {
log.info("------------------------------HttpClient POST開始-------------------------------");
log.info("POST:" + url);
log.info("filePath:" + filePath);
if (StringUtils.isBlank(url)) {
log.error("post請求不合法错英,請檢查uri參數(shù)!");
return null;
}
StringBuilder content = new StringBuilder();
// 模擬表單上傳 POST 提交主體內容
String boundary = "-----------------------------" + new Date().getTime();
// 待上傳的文件
File file = new File(filePath);
if (!file.exists() || file.isDirectory()) {
log.error(filePath + ":不是一個有效的文件路徑");
return null;
}
// 響應內容
String respContent = null;
InputStream is = null;
OutputStream os = null;
BufferedInputStream bis = null;
File tempFile = null;
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
try {
// 創(chuàng)建臨時文件入撒,將post內容保存到該臨時文件下,臨時文件保存在系統(tǒng)默認臨時目錄下椭岩,使用系統(tǒng)默認文件名稱
tempFile = File.createTempFile(new SimpleDateFormat("yyyy_MM_dd").format(new Date()), null);
os = new FileOutputStream(tempFile);
is = new FileInputStream(file);
os.write(("--" + boundary + "\r\n").getBytes());
os.write(String.format(
"Content-Disposition: form-data; name=\"media\"; filename=\"" + file.getName() + "\"\r\n")
.getBytes());
os.write(String.format("Content-Type: %s\r\n\r\n", FileHelper.getMimeType(file)).getBytes());
// 讀取上傳文件
bis = new BufferedInputStream(is);
byte[] buff = new byte[8096];
int len = 0;
while ((len = bis.read(buff)) != -1) {
os.write(buff, 0, len);
}
os.write(("\r\n--" + boundary + "--\r\n").getBytes());
httpClient = HttpClients.createDefault();
// 創(chuàng)建POST請求
httpPost = new HttpPost(url);
// 創(chuàng)建請求實體
FileEntity reqEntity = new FileEntity(tempFile, ContentType.MULTIPART_FORM_DATA);
// 設置請求編碼
reqEntity.setContentEncoding("UTF-8");
httpPost.setEntity(reqEntity);
// 執(zhí)行請求
HttpResponse response = httpClient.execute(httpPost);
// 獲取響應內容
respContent = repsonse(response);
if(respContent.startsWith("code")) {
log.info("resp:" + respContent);
throw new RuntimeException("請求失敗茅逮,請檢查URL地址和請求參數(shù)...");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient POST結束-------------------------------");
return respContent;
}
- 下載多媒體文件主函數(shù)
/**
* HttpClient GET請求,可接受普通文本JSON等
*
* @param uri Y 請求URL判哥,參數(shù)封裝
* @return 響應字符串
* @author Jie
* @date 2015-2-12
*/
public static String getForDownloadStream(String uri, String targetPath) throws IOException {
log.info("------------------------------HttpClient GET BEGIN-------------------------------");
log.info("GET:" + uri);
if (StringUtils.isBlank(uri) || StringUtils.isBlank(targetPath)) {
throw new RuntimeException(" uri or targetPath parameter is null or is empty!");
}
// 創(chuàng)建GET請求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = null;
String respContent = "";
try {
httpGet = new HttpGet(uri);
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();// 響應碼
String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
if (statusCode == 200) {// 請求成功
// 獲取響應MineType
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.get(entity);
if (mineTypeList.contains(contentType.getMimeType().toLowerCase())) {
log.info("MineType:" + contentType.getMimeType());
if (targetPath.contains(".")) {
targetPath = targetPath.substring(0, targetPath.lastIndexOf(".")) + "."
+ contentType.getMimeType().split("/")[1];
} else if (targetPath.endsWith(File.separator)) {
targetPath += UUID.randomUUID().toString() + "." + contentType.getMimeType().split("/")[1];
} else {
targetPath += File.separator + UUID.randomUUID().toString() + "."
+ contentType.getMimeType().split("/")[1];
}
// 寫入磁盤
respContent = FileHelper.writeFile(entity.getContent(), targetPath);
} else {
respContent = repsonse(response);
}
} else {
log.error("resp:code[" + statusCode + "],desc[" + reasonPhrase + "]");
throw new RuntimeException("請求失敗献雅,請檢查請求地址及參數(shù)");
}
} finally {
if (httpGet != null)
httpGet.releaseConnection();
if (httpClient != null)
// noinspection ThrowFromFinallyBlock
httpClient.close();
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient GET END-------------------------------");
return respContent;
}
微信示例測試
-
上傳
上傳到微信服務器 -
下載
從微信服務器下載到本地
- 最后,附上完整的工具類
package org.os.tools;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* 常用工具類:Apache HttpClient工具
*
* @author Jie
* @date 2015-2-12
* @since JDK1.6
*/
public class HttpClientHelper {
private static Logger log = Logger.getLogger(HttpClientHelper.class);
private static List<String> mineTypeList = new ArrayList<String>();
static {
mineTypeList.add("application/octet-stream");
mineTypeList.add("application/pdf");
mineTypeList.add("application/msword");
mineTypeList.add("image/png");
mineTypeList.add("image/jpg");
mineTypeList.add("image/jpeg");
mineTypeList.add("image/gif");
mineTypeList.add("image/bmp");
mineTypeList.add("audio/amr");
mineTypeList.add("audio/mp3");
mineTypeList.add("audio/aac");
mineTypeList.add("audio/wma");
mineTypeList.add("audio/wav");
mineTypeList.add("video/mpeg");
}
/***
* HttpClient GET請求塌计,Header參數(shù)
*
* @param uri 請求地址
* @param name 參數(shù)名稱
* @param value 參數(shù)值
* @return 響應字符串
* @author Jie
* @date 2015年7月7日
*/
public static String getMethod(String uri, String name, String value) throws IOException {
log.info("------------------------------HttpClient GET BEGIN-------------------------------");
log.info("GET:" + uri);
if (StringUtils.isBlank(uri)) {
throw new RuntimeException(" uri parameter is null or is empty!");
}
log.info("req:[" + name + "=" + value + "]");
CloseableHttpClient httpClient = null;
HttpGet httpGet = null;
String respContent = null;
try {
// 創(chuàng)建GET請求
httpClient = HttpClients.createDefault();
httpGet = new HttpGet(uri);
httpGet.addHeader(name, value);
// 提交GET請求
HttpResponse response = httpClient.execute(httpGet);
// 獲取響應內容
respContent = repsonse(response);
if (respContent.startsWith("code")) {
log.info("resp:" + respContent);
throw new RuntimeException("請求失敗挺身,請檢查URL地址和請求參數(shù)...");
}
} finally {
if (httpGet != null) {
httpGet.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient GET END-------------------------------");
return respContent;
}
/**
* HttpClient GET請求,可接受普通文本JSON等
*
* @param uri Y 請求URL锌仅,參數(shù)封裝
* @return 響應字符串
* @author Jie
* @date 2015-2-12
*/
public static String getMethod(String uri) throws IOException {
log.info("------------------------------HttpClient GET BEGIN-------------------------------");
log.info("GET:" + uri);
if (StringUtils.isBlank(uri)) {
throw new RuntimeException(" uri parameter is null or is empty!");
}
// 創(chuàng)建GET請求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = null;
String respContent = "";
try {
httpGet = new HttpGet(uri);
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();// 響應碼
String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
if (statusCode == 200) {// 請求成功
// 獲取響應MineType
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.get(entity);
if (mineTypeList.contains(contentType.getMimeType().toLowerCase())) {// 下載失敗
log.info("MineType:" + contentType.getMimeType());
} else {
respContent = repsonse(response);
}
} else {
log.error("resp:code[" + statusCode + "],desc[" + reasonPhrase + "]");
throw new RuntimeException("請求失敗章钾,請檢查請求地址及參數(shù)");
}
} finally {
if (httpGet != null)
httpGet.releaseConnection();
if (httpClient != null)
// noinspection ThrowFromFinallyBlock
httpClient.close();
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient GET END-------------------------------");
return respContent;
}
/**
* HttpClient GET請求,可接受普通文本JSON等
*
* @param uri Y 請求URL热芹,參數(shù)封裝
* @return 響應字符串
* @author Jie
* @date 2015-2-12
*/
public static String getForDownloadStream(String uri, String targetPath) throws IOException {
log.info("------------------------------HttpClient GET BEGIN-------------------------------");
log.info("GET:" + uri);
if (StringUtils.isBlank(uri) || StringUtils.isBlank(targetPath)) {
throw new RuntimeException(" uri or targetPath parameter is null or is empty!");
}
// 創(chuàng)建GET請求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = null;
String respContent = "";
try {
httpGet = new HttpGet(uri);
HttpResponse response = httpClient.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();// 響應碼
String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
if (statusCode == 200) {// 請求成功
// 獲取響應MineType
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.get(entity);
if (mineTypeList.contains(contentType.getMimeType().toLowerCase())) {
log.info("MineType:" + contentType.getMimeType());
if (targetPath.contains(".")) {
targetPath = targetPath.substring(0, targetPath.lastIndexOf(".")) + "."
+ contentType.getMimeType().split("/")[1];
} else if (targetPath.endsWith(File.separator)) {
targetPath += UUID.randomUUID().toString() + "." + contentType.getMimeType().split("/")[1];
} else {
targetPath += File.separator + UUID.randomUUID().toString() + "."
+ contentType.getMimeType().split("/")[1];
}
// 寫入磁盤
respContent = FileHelper.writeFile(entity.getContent(), targetPath);
} else {
respContent = repsonse(response);
}
} else {
log.error("resp:code[" + statusCode + "],desc[" + reasonPhrase + "]");
throw new RuntimeException("請求失敗贱傀,請檢查請求地址及參數(shù)");
}
} finally {
if (httpGet != null)
httpGet.releaseConnection();
if (httpClient != null)
// noinspection ThrowFromFinallyBlock
httpClient.close();
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient GET END-------------------------------");
return respContent;
}
/**
* HttpClient POST請求 ,傳參方式:key-value
*
* @param uri 請求地址
* @param params 參數(shù)列表
* @return 響應字符串
* @author Jie
* @date 2015-2-12
*/
@SuppressWarnings("ThrowFromFinallyBlock")
public static String postMethod(String uri, List<NameValuePair> params) throws IOException {
log.info("------------------------------HttpClient POST BEGIN-------------------------------");
log.info("POST:" + uri);
if (StringUtils.isBlank(uri)) {
throw new RuntimeException(" uri parameter is null or is empty!");
}
log.info("req:" + params);
// 創(chuàng)建GET請求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = null;
String respContent = null;
try {
httpPost = new HttpPost(uri);
httpPost.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
// 執(zhí)行請求
HttpResponse response = httpClient.execute(httpPost);
// 獲取響應內容
respContent = repsonse(response);
if (respContent.startsWith("code")) {
log.info("resp:" + respContent);
throw new RuntimeException("請求失敗,請檢查URL地址和請求參數(shù)...");
}
} finally {
close(null, null, null, httpPost, httpClient);
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient POST END-------------------------------");
return respContent;
}
/**
* HttpClient POST請求 ,上傳多媒體文件
*
* @param url 請求地址
* @param filePath 多媒體文件絕對路徑
* @return 多媒體文件ID
* @throws UnsupportedEncodingException
* @author Jie
* @date 2015-2-12
*/
@SuppressWarnings("resource")
public static String postForUploadStream(String url, String filePath) throws IOException {
log.info("------------------------------HttpClient POST開始-------------------------------");
log.info("POST:" + url);
log.info("filePath:" + filePath);
if (StringUtils.isBlank(url)) {
log.error("post請求不合法伊脓,請檢查uri參數(shù)!");
return null;
}
StringBuilder content = new StringBuilder();
// 模擬表單上傳 POST 提交主體內容
String boundary = "-----------------------------" + new Date().getTime();
// 待上傳的文件
File file = new File(filePath);
if (!file.exists() || file.isDirectory()) {
log.error(filePath + ":不是一個有效的文件路徑");
return null;
}
// 響應內容
String respContent = null;
InputStream is = null;
OutputStream os = null;
BufferedInputStream bis = null;
File tempFile = null;
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
try {
// 創(chuàng)建臨時文件府寒,將post內容保存到該臨時文件下,臨時文件保存在系統(tǒng)默認臨時目錄下报腔,使用系統(tǒng)默認文件名稱
tempFile = File.createTempFile(new SimpleDateFormat("yyyy_MM_dd").format(new Date()), null);
os = new FileOutputStream(tempFile);
is = new FileInputStream(file);
os.write(("--" + boundary + "\r\n").getBytes());
os.write(String.format(
"Content-Disposition: form-data; name=\"media\"; filename=\"" + file.getName() + "\"\r\n")
.getBytes());
os.write(String.format("Content-Type: %s\r\n\r\n", FileHelper.getMimeType(file)).getBytes());
// 讀取上傳文件
bis = new BufferedInputStream(is);
byte[] buff = new byte[8096];
int len = 0;
while ((len = bis.read(buff)) != -1) {
os.write(buff, 0, len);
}
os.write(("\r\n--" + boundary + "--\r\n").getBytes());
httpClient = HttpClients.createDefault();
// 創(chuàng)建POST請求
httpPost = new HttpPost(url);
// 創(chuàng)建請求實體
FileEntity reqEntity = new FileEntity(tempFile, ContentType.MULTIPART_FORM_DATA);
// 設置請求編碼
reqEntity.setContentEncoding("UTF-8");
httpPost.setEntity(reqEntity);
// 執(zhí)行請求
HttpResponse response = httpClient.execute(httpPost);
// 獲取響應內容
respContent = repsonse(response);
if(respContent.startsWith("code")) {
log.info("resp:" + respContent);
throw new RuntimeException("請求失敗株搔,請檢查URL地址和請求參數(shù)...");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
if (httpPost != null) {
httpPost.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient POST結束-------------------------------");
return respContent;
}
/**
* 獲取響應內容,針對MimeType為text/plan纯蛾、text/json格式
*
* @param response HttpResponse對象
* @return 轉為UTF-8的字符串
* @author Jie
* @date 2015-2-28
*/
private static String repsonse(HttpResponse response) throws ParseException, IOException {
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();// 響應碼
String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
StringBuilder content = new StringBuilder();
if (statusCode == HttpStatus.SC_OK) {// 請求成功
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.get(entity);
log.info("MineType:" + contentType.getMimeType());
content.append(EntityUtils.toString(entity, Consts.UTF_8));
} else {
content.append("code[").append(statusCode).append("],desc[").append(reasonPhrase).append("]");
}
return content.toString().replace("\r\n", "").replace("\n", "");
}
// 釋放資源
private static void close(File tempFile, OutputStream os, InputStream is, HttpPost httpPost,
CloseableHttpClient httpClient) throws IOException {
if (tempFile != null && tempFile.exists() && !tempFile.delete()) {
tempFile.deleteOnExit();
}
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
if (httpPost != null) {
// 釋放資源
httpPost.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
}
/**
* HttpClient POST請求 ,可接受普通字符響應纤房,也可支持下載多媒體文件
*
* @param uri Y 請求地址
* @param params Y 請求參數(shù)串,推薦使用JSON格式
* @return 響應字符串
* @author Jie
* @date 2016年4月8日
*/
public static String postMethod(String uri, String params) throws IOException {
log.info("------------------------------HttpClient POST BEGIN-------------------------------");
log.info("uri:" + uri);
if (StringUtils.isBlank(uri)) {
throw new RuntimeException(" uri parameter is null or is empty!");
}
// 響應內容
InputStream is = null;
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
String respContent = "";
try {
httpClient = HttpClients.createDefault();
// 創(chuàng)建POST請求
httpPost = new HttpPost(uri);
httpPost.setEntity(new StringEntity(params, Consts.UTF_8));
// 執(zhí)行請求
HttpResponse response = httpClient.execute(httpPost);
// 獲取響應信息
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
if (statusCode == HttpStatus.SC_OK) {// 請求成功
HttpEntity entity = response.getEntity();
ContentType contentType = ContentType.get(entity);
if (mineTypeList.contains(contentType.getMimeType().toLowerCase())) {
log.info("MineType :" + contentType.getMimeType());
respContent = StreamHelper.read(entity.getContent());
} else {
// 獲取響應內容
respContent = repsonse(response);
if (respContent.startsWith("code")) {
log.info("resp:" + respContent);
throw new RuntimeException("請求失敗茅撞,請檢查URL地址和請求參數(shù)...");
}
}
} else {
log.error("code[" + statusCode + "],desc[" + reasonPhrase + "]");
throw new RuntimeException("請求失敗帆卓,請檢查請求地址或請求參數(shù)");
}
} finally {
// noinspection ThrowFromFinallyBlock
close(null, null, is, httpPost, httpClient);
}
log.info("resp:" + respContent);
log.info("------------------------------HttpClient POST END-------------------------------");
return respContent;
}
public static void main(String[] args) {
String s = String.format("asdlkfajfk%naskdfjdlksaf");
System.out.println(s);
}
}
- 寫入文件函數(shù)
/**
* 寫入文件到目標磁盤中
*
* @param in 文件輸入流
* @param targetPath 文件存放目標絕對路徑(包含文件)
* @return
* @author Jie
* @throws Exception
* @date 2015-2-12
*/
public static String writeFile(InputStream in, String targetPath) throws IOException {
if (in == null) {
log.error("The InputStream is null");
return "未能獲取到輸入流";
}
if (StringUtils.isBlank(targetPath)) {
log.error("The targetPath is null");
return "文件保存路徑不可為空";
}
OutputStream os = null;
try {
File file = new File(targetPath);
if (file.isDirectory()) {
return "保存的文件應是一個文件巨朦,而非一個目錄";
}
os = new FileOutputStream(file);
int len = 0;
byte[] ch = new byte[1024];
while ((len = in.read(ch)) != -1) {
os.write(ch, 0, len);
}
log.info("File save success : " + file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
return "保存文件到磁盤異常:" + e.getMessage();
} finally {
close(os, null);
}
return "成功";
}
- 獲取文件MineType
/**
* 獲文件類型
* @param file 目標文件
* @return MimeType
* @author Jie
* @date 2015-2-28
*/
public static String getMimeType(File file) {
return new MimetypesFileTypeMap().getContentType(file);
}