上一节讲了获取证书,这一节讲一下图片上传
先来看一下官方提供的文档
官方文档:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_9
接口规则
请求Url | https://api.mch.weixin.qq.com/secapi/mch/uploadmedia |
---|---|
提交方式 | multipart/form-data |
是否需要证书 | 是, 详见证书使用 |
特别注意,该接口调用是需要用到证书的,具体的获取和使用请参考:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=4_3
WxUploadMediaBo.java
package com.pay.wechat.bo.small;
import java.io.File;
import java.io.FileInputStream;
import java.util.UUID;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import com.dlys.pay.wechat.protocol.WxUploadMediaModel;
import com.dlys.pay.wechat.util.HttpsRequest;
import com.dlyspublic.util.Config;
/**
* 微信上传文件工具
*
* @author libaibai
* @version 1.0 2020年5月26日
*/
@Component
public class WxUploadMediaBo {
public void exe(MultipartFile multipartFile) throws Exception {
File excelFile = File.createTempFile(UUID.randomUUID().toString(), ".jpg");
multipartFile.transferTo(excelFile);
FileBody bin = new FileBody(excelFile, ContentType.create("image/jpg", Consts.UTF_8));
String hash = DigestUtils.md5Hex(multipartFile.getBytes());
WxUploadMediaModel model = new WxUploadMediaModel(hash, Config.APIKEY);
String sign = model.getSign();
HttpEntity httpEntity = MultipartEntityBuilder.create().addPart("media", bin).addTextBody("mch_id", Config.MCHIDSP)
.addTextBody("media_hash", hash).addTextBody("sign", sign).addTextBody("sign_type", "HMAC-SHA256").build();
try {
String url = "https://api.mch.weixin.qq.com/secapi/mch/uploadmedia";
HttpsRequest request = new HttpsRequest();
String str = request.sendPostObject(url, httpEntity);
System.out.println(str);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
WxUploadMediaBo test = new WxUploadMediaBo();
String p = "C:\\Users\\lift.CHINATENET\\Desktop\\文档\\停车场照片\\1.jpg";
try {
File file = new File(p);
MultipartFile multipartFile = new MockMultipartFile("file", new FileInputStream(file));
test.exe(multipartFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
HttpsReqest.java
package com.pay.wechat.util;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.ContentType;
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.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Component;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import net.sf.json.JSONObject;
/**
* HTTP 请求类
*
* @author libaibai
* @version 1.0 2020年5月26日
*/
@Component
public class HttpsRequest {
public interface ResultListener {
public void onConnectionPoolTimeoutError();
}
private static Logger LOG = LogManager.getLogger(HttpsRequest.class);
private boolean hasInit = false;
// 连接超时时间,默认10秒
private int socketTimeout = 10000;
// 传输超时时间,默认30秒
private int connectTimeout = 30000;
// 请求器的配置
private RequestConfig requestConfig;
// HTTP请求器
private CloseableHttpClient httpClient;
/**
* 证书初始化
*
* @throws UnrecoverableKeyException
* @throws KeyManagementException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws IOException
*/
public HttpsRequest() throws UnrecoverableKeyException, KeyManagementException,
NoSuchAlgorithmException, KeyStoreException, IOException {
init();
}
private void init() throws IOException, KeyStoreException, UnrecoverableKeyException,
NoSuchAlgorithmException, KeyManagementException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream instream = HttpsRequest.class.getClassLoader().getResourceAsStream(
Configure.CERTLOCAL_PATHx);// 加载本地的证书进行https加密传输
try {
keyStore.load(instream, Configure.CERTPASSWORD.toCharArray());// 设置证书密码
} catch (Exception e) {
LOG.error("加载证书异常", e);
} finally {
instream.close();
}
SSLContext sslcontext = SSLContexts.custom()
.loadKeyMaterial(keyStore, Configure.CERTPASSWORD.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,
new String[] { "TLSv1" }, null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
// 根据默认超时限制初始化requestConfig
requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout).build();
hasInit = true;
}
/**
* 通过Https往API GET
*
* @param url API地址
* @return API回包的实际数据
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String sendGET(String url) throws IOException, KeyStoreException,
UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
if (!hasInit) {
init();
}
String result = null;
HttpGet httpGet = new HttpGet(url);
// 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
httpGet.addHeader("Content-Type", "text/xml");
// 设置请求器的配置
httpGet.setConfig(requestConfig);
try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
LOG.error("HTTP Get请示异常", e);
} finally {
httpGet.abort();
}
return result;
}
/**
* 通过Https往API post
*
* @param url API地址
* @param Object 要提交的Object数据对象
* @return API回包的实际数据
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String sendPostObject(String url, HttpEntity postEntity) throws IOException, KeyStoreException,
UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
if (!hasInit) {
init();
}
String result = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA.getMimeType());
httpPost.setEntity(postEntity);
// 设置请求器的配置
httpPost.setConfig(requestConfig);
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
LOG.error("HTTP POST 请求异常", e);
} finally {
httpPost.abort();
}
return result;
}
/**
* 通过Https往API post xml数据
*
* @param url API地址
* @param xmlObj 要提交的XML数据对象
* @return API回包的实际数据
* @throws IOException
* @throws KeyStoreException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public String sendPost(String url, Object xmlObj) throws IOException, KeyStoreException,
UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException {
if (!hasInit) {
init();
}
String result = null;
HttpPost httpPost = new HttpPost(url);
// 解决XStream对出现双下划线的bug
XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8",
new XmlFriendlyNameCoder("-_", "_")));
// 将要提交给API的数据对象转换成XML格式数据Post给API
String postDataXML = xStreamForRequestPostData.toXML(xmlObj);
// LOG.info("请求微信接口->url="+url+",data="+postDataXML);
// 得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别
StringEntity postEntity = new StringEntity(postDataXML, "UTF-8");
httpPost.addHeader("Content-Type", "text/xml");
httpPost.setEntity(postEntity);
// 设置请求器的配置
httpPost.setConfig(requestConfig);
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
LOG.error("HTTP POST 请求异常", e);
} finally {
// httpPost.abort();
httpPost.releaseConnection();
}
return result;
}
/**
* 设置连接超时时间
*
* @param socketTimeout 连接时长,默认10秒
*/
public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
resetRequestConfig();
}
/**
* 设置传输超时时间
*
* @param connectTimeout 传输时长,默认30秒
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
resetRequestConfig();
}
private void resetRequestConfig() {
requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
.setConnectTimeout(connectTimeout).build();
}
/**
* 允许商户自己做更高级更复杂的请求器配置
*
* @param requestConfig 设置HttpsRequest的请求器配置
*/
public void setRequestConfig(RequestConfig requestConfig) {
this.requestConfig = requestConfig;
}
}
运行main方式得到返回结果
<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<result_code><![CDATA[SUCCESS]]></result_code>
<media_id><![CDATA[HmddyW8NdBxhqQr_L1IEz6NiwSG6BzCCFVqsGKqO-d8mBsLI3KVj3Xwmixfqme-X7OeLHW0jrSBLEo3nCioKXqq6OQddGEj_SNRhd-5qI8I]]></media_id>
<sign><![CDATA[D0FF0FC24B6C51719A4D5CD4C95D721F]]></sign>
</xml>
ok,图片上传成功。