mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-09-24 04:53:50 +08:00
添加多媒体文件下载支持
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package chanjarster.weixin.api;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.MessageDigest;
|
||||
@@ -10,15 +9,9 @@ import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.Consts;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
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.StringEntity;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.BasicResponseHandler;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
@@ -29,7 +22,12 @@ import chanjarster.weixin.bean.WxMenu;
|
||||
import chanjarster.weixin.bean.result.WxError;
|
||||
import chanjarster.weixin.bean.result.WxUploadResult;
|
||||
import chanjarster.weixin.exception.WxErrorException;
|
||||
import chanjarster.weixin.util.Utf8ResponseHandler;
|
||||
import chanjarster.weixin.util.fs.FileUtil;
|
||||
import chanjarster.weixin.util.http.MediaDownloadRequestExecutor;
|
||||
import chanjarster.weixin.util.http.MediaUploadRequestExecutor;
|
||||
import chanjarster.weixin.util.http.RequestExecutor;
|
||||
import chanjarster.weixin.util.http.SimpleGetRequestExecutor;
|
||||
import chanjarster.weixin.util.http.SimplePostRequestExecutor;
|
||||
|
||||
public class WxServiceImpl implements WxService {
|
||||
|
||||
@@ -62,7 +60,7 @@ public class WxServiceImpl implements WxService {
|
||||
}
|
||||
}
|
||||
|
||||
protected static String bytesToHex(byte[] b) {
|
||||
protected String bytesToHex(byte[] b) {
|
||||
char hexDigit[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
StringBuffer buf = new StringBuffer();
|
||||
@@ -110,25 +108,25 @@ public class WxServiceImpl implements WxService {
|
||||
}
|
||||
}
|
||||
|
||||
public String sendCustomMessage(WxCustomMessage message) throws WxErrorException {
|
||||
public void sendCustomMessage(WxCustomMessage message) throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/message/custom/send";
|
||||
return post(url, message.toJson());
|
||||
execute(new SimplePostRequestExecutor(), url, message.toJson());
|
||||
}
|
||||
|
||||
public String createMenu(WxMenu menu) throws WxErrorException {
|
||||
public void createMenu(WxMenu menu) throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/create";
|
||||
return post(url, menu.toJson());
|
||||
execute(new SimplePostRequestExecutor(), url, menu.toJson());
|
||||
}
|
||||
|
||||
public String deleteMenu() throws WxErrorException {
|
||||
public void deleteMenu() throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/delete";
|
||||
return get(url, null);
|
||||
execute(new SimpleGetRequestExecutor(), url, null);
|
||||
}
|
||||
|
||||
public WxMenu getMenu() throws WxErrorException {
|
||||
String url = "https://api.weixin.qq.com/cgi-bin/menu/get";
|
||||
try {
|
||||
String resultContent = get(url, null);
|
||||
String resultContent = execute(new SimpleGetRequestExecutor(), url, null);
|
||||
return WxMenu.fromJson(resultContent);
|
||||
} catch (WxErrorException e) {
|
||||
// 46003 不存在的菜单数据
|
||||
@@ -140,30 +138,28 @@ public class WxServiceImpl implements WxService {
|
||||
}
|
||||
|
||||
public WxUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException, IOException {
|
||||
return uploadMedia(mediaType, createTmpFile(inputStream, fileType));
|
||||
return uploadMedia(mediaType,FileUtil.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
|
||||
}
|
||||
|
||||
public WxUploadResult uploadMedia(String mediaType, File file) throws WxErrorException {
|
||||
String url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType;
|
||||
String json = post(url, file);
|
||||
return WxUploadResult.fromJson(json);
|
||||
return execute(new MediaUploadRequestExecutor(), url, file);
|
||||
}
|
||||
|
||||
protected String post(String uri, Object data) throws WxErrorException {
|
||||
return execute("POST", uri, data);
|
||||
}
|
||||
|
||||
protected String get(String uri, Object data) throws WxErrorException {
|
||||
return execute("GET", uri, data);
|
||||
public File downloadMedia(String media_id) throws WxErrorException {
|
||||
String url = "http://file.api.weixin.qq.com/cgi-bin/media/get";
|
||||
return execute(new MediaDownloadRequestExecutor(), url, "media_id=" + media_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
|
||||
* @param request
|
||||
* @return 微信服务端返回的结果
|
||||
* @throws WxErrorException
|
||||
* @param executor
|
||||
* @param uri
|
||||
* @param data
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
*/
|
||||
protected String execute(String method, String uri, Object data) throws WxErrorException {
|
||||
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
|
||||
if (StringUtils.isBlank(wxConfigStorage.getAccessToken())) {
|
||||
refreshAccessToken();
|
||||
}
|
||||
@@ -173,38 +169,9 @@ public class WxServiceImpl implements WxService {
|
||||
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;
|
||||
|
||||
try {
|
||||
String resultContent = null;
|
||||
if ("POST".equals(method)) {
|
||||
HttpPost httpPost = new HttpPost(uriWithAccessToken);
|
||||
if (data != null) {
|
||||
if (data instanceof String) {
|
||||
StringEntity entity = new StringEntity((String)data, Consts.UTF_8);
|
||||
httpPost.setEntity(entity);
|
||||
}
|
||||
if (data instanceof File) {
|
||||
File file = (File) data;
|
||||
HttpEntity entity = MultipartEntityBuilder
|
||||
.create()
|
||||
.addBinaryBody("media", file)
|
||||
.build();
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString());
|
||||
}
|
||||
}
|
||||
CloseableHttpResponse response = httpclient.execute(httpPost);
|
||||
resultContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
|
||||
} else if ("GET".equals(method)) {
|
||||
if (data != null) {
|
||||
if (data instanceof String) {
|
||||
uriWithAccessToken += uriWithAccessToken.endsWith("&") ? data : '&' + (String)data;
|
||||
}
|
||||
}
|
||||
HttpGet httpGet = new HttpGet(uriWithAccessToken);
|
||||
CloseableHttpResponse response = httpclient.execute(httpGet);
|
||||
resultContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
|
||||
}
|
||||
|
||||
WxError error = WxError.fromJson(resultContent);
|
||||
return executor.execute(uriWithAccessToken, data);
|
||||
} catch (WxErrorException e) {
|
||||
WxError error = e.getError();
|
||||
/*
|
||||
* 发生以下情况时尝试刷新access_token
|
||||
* 40001 获取access_token时AppSecret错误,或者access_token无效
|
||||
@@ -212,12 +179,24 @@ public class WxServiceImpl implements WxService {
|
||||
*/
|
||||
if (error.getErrcode() == 42001 || error.getErrcode() == 40001) {
|
||||
refreshAccessToken();
|
||||
return execute(method, uri, data);
|
||||
return execute(executor, uri, data);
|
||||
}
|
||||
/**
|
||||
* -1 系统繁忙, 500ms后重试
|
||||
*/
|
||||
if (error.getErrcode() == -1) {
|
||||
try {
|
||||
System.out.println("微信系统繁忙,500ms后重试");
|
||||
Thread.sleep(500);
|
||||
return execute(executor, uri, data);
|
||||
} catch (InterruptedException e1) {
|
||||
throw new RuntimeException(e1);
|
||||
}
|
||||
}
|
||||
if (error.getErrcode() != 0) {
|
||||
throw new WxErrorException(error);
|
||||
}
|
||||
return resultContent;
|
||||
return null;
|
||||
} catch (ClientProtocolException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
@@ -225,38 +204,8 @@ public class WxServiceImpl implements WxService {
|
||||
}
|
||||
}
|
||||
|
||||
protected File createTmpFile(InputStream inputStream, String fileType) throws IOException {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
File tmpFile = File.createTempFile(UUID.randomUUID().toString(), '.' + fileType);
|
||||
tmpFile.deleteOnExit();
|
||||
fos = new FileOutputStream(tmpFile);
|
||||
int read = 0;
|
||||
byte[] bytes = new byte[1024 * 100];
|
||||
while ((read = inputStream.read(bytes)) != -1) {
|
||||
fos.write(bytes, 0, read);
|
||||
}
|
||||
fos.flush();
|
||||
return tmpFile;
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setWxConfigStorage(WxConfigStorage wxConfigProvider) {
|
||||
this.wxConfigStorage = wxConfigProvider;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user