对接微信消费者2.0接口(上传图片)
第一步 collection调研service,传递一个DTO类。
@Override
@Transactional(rollbackFor = Exception.class)
public void doSubmitAnswers(SubmitComplaintRequestDTO submitComplaintDTO) throws Exception {
int type = complaintMapper.findComplaintTypeByCId(submitComplaintDTO.getComplaintId());
//这里说明一下,type是业务,公司有会员订单和支付租赁2个业务,2个微信授权信息
//=======================================================================
//获取具体投诉信息
String merchantPrivateKey = "";
String mchId = "";
String serialNo = "";
String key = "";
switch (type){
case 1:
//租借
merchantPrivateKey = propertiesConfig.merchantPrivateKey;
mchId = propertiesConfig.wxMchId;
serialNo = propertiesConfig.serialNo;
key = propertiesConfig.wxKey;
break;
case 2:
//会员
merchantPrivateKey = propertiesConfig.memberMerchantPrivateKey;
mchId = propertiesConfig.wxMemberMchId;
serialNo = propertiesConfig.memberSerialNo;
key = propertiesConfig.wxMemberKey;
break;
default:
throw new ServiceException(Constant.API_RESPONSE_SERVICE_ERROR, "微信投诉单提交回复V3 type 参数异常:" + type);
}
//-------------------------------------------------------------------------
//上传图片逻辑处理 *****重点*****
List<String> imgUploadList = new ArrayList<String>();
if(submitComplaintDTO.getImgList() != null && submitComplaintDTO.getImgList().size() > 0){
//判断 前台给传递了url 才进行图片上传。(其实我建议 上传一次走一次接口,也就是上传图片接口独立出去,我这么做一次上传4个也是偷懒写法,不建议这么弄,因为我们这个后台系统没什么并发量,一天也就百来个投诉,所以简化了。)
logger.info("[开始上传图片]......【1】");
List<String> baseImgList = submitComplaintDTO.getImgList();
//获取前端传递的 base64后的url字符串,微信要求最多4张
if(baseImgList.size() > 4){
throw new ServiceException(Constant.API_RESPONSE_SERVICE_ERROR, "最多上传4张图片 size:" + baseImgList.size());
}
//初始化准备
CloseableHttpClient httpClient = null;
AutoUpdateCertificatesVerifier verifier = null;
try{
//私钥(微信sdk都有,maven引入jar就行)
PrivateKey merchantPrivateKey_img = PemUtil.loadPrivateKey(
new ByteArrayInputStream(merchantPrivateKey.getBytes("utf-8")));
logger.info("[开始上传图片]......【2】 拿私钥");
//使用自动更新的签名验证器,不需要传入证书
verifier = new AutoUpdateCertificatesVerifier(
new WechatPay2Credentials(mchId, new PrivateKeySigner(serialNo, merchantPrivateKey_img)),
key.getBytes("utf-8"));
logger.info("[开始上传图片]......【3】 证书");
httpClient = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, serialNo, merchantPrivateKey_img)
.withValidator(new WechatPay2Validator(verifier))
.build();
logger.info("[开始上传图片]......【4】创建httpClient");
//WX_COMPLAINT_UPLOAD_IMG_URI 看微信api上面都有 private static final String WX_COMPLAINT_UPLOAD_IMG_URI = "https://api.mch.weixin.qq.com/v3/merchant-service/images/upload";
URI uri = new URI(WX_COMPLAINT_UPLOAD_IMG_URI.replace("{complaint_id}", submitComplaintDTO.getComplaintId()));
logger.info("[开始上传图片]......【5】创建URI");
for (String base64:baseImgList){
String fileName = base64.split(",")[0];
CloseableHttpResponse responseImg = null;
//这里注意 使用MultipartFile 转换 (不需要下载本地临时地址,上传后删除,直接使用MultipartFile转换inputStream流进行上传
MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(base64);
File newFile = new File(fileName); FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), newFile);
logger.info("[开始上传图片]......fileName----->" + fileName);
FileInputStream s1 = new FileInputStream(newFile);
String sha256 = DigestUtils.sha256Hex(s1);
logger.info("反馈问题上传图片,sha256={}",sha256);
InputStream s2 = new FileInputStream(newFile);
WechatPayUploadHttpPost request = new WechatPayUploadHttpPost.Builder(uri)
.withImage(newFile.getName(), sha256, s2)
.build();
responseImg = httpClient.execute(request);
logger.info("[上传图片]......【完成】------>fileName----->" + fileName);
try {
HttpEntity entity1 = responseImg.getEntity();
String s = EntityUtils.toString(entity1);
logger.info("图片上传成功:media_id={}",s);
JSONObject jsonObject = JSONObject.parseObject(s);
imgUploadList.add(jsonObject.get("media_id").toString());
} finally {
if(responseImg != null){
responseImg.close();
}
}
}
}catch (IOException e){
logger.error("提交回复,上传图片请求异常={}",e.getMessage());
throw new ServiceException(Constant.API_RESPONSE_SERVICE_ERROR, "提交回复,上传图片请求异常:" + e.getMessage());
}finally {
if(httpClient != null) {
httpClient.close();
}
}
}
//这下面就是 提交反馈接口调用了,把之前反馈meat字符串扔进去就OK了
CloseableHttpResponse response = null;
CloseableHttpClient httpClient = null;
//拼接URL
String url = WX_COMPLAINT_SUBMIT_URL.replace("{complaint_id}", submitComplaintDTO.getComplaintId());
//组装body内容
String responseImages = "";
if(imgUploadList.size() > 0){
responseImages = ",\"response_images\": [";
for(int i = 0;i < imgUploadList.size();i++){
responseImages += ("\"" + imgUploadList.get(i) + "\"");
if(i < imgUploadList.size() - 1){
responseImages += ",";
}
}
responseImages += "]";
}
String strBody = "{\"complainted_mchid\": \"" + mchId + "\",\"response_content\":\"" + submitComplaintDTO.getAnswer() +"\"" + responseImages + "}";
// {
// "complainted_mchid": "1900012181",
// "response_content": "已与用户沟通解决",
// "response_images": [
// "file23578_21798531.jpg",
// "file23578_21798532.jpg",
// ......
// ]
// }
// 指定头信息
Map<String, String> headerMap = new HashMap<String, String>();
headerMap.put("Accept", "application/json");
try{
httpClient = HttpClientConnectionManager.getSSLAutoUpdateInstance(merchantPrivateKey, mchId, serialNo, key);
response = httpClient.execute(HttpClientConnectionManager.getPostMethod(url,headerMap,strBody));
}catch (Exception e) {
logger.error("微信提交投诉回复异常V3 请求url={} ,body={} 异常 Exception={},response={}", url,strBody, e.getMessage(),response.toString());
throw new ServiceException(Constant.API_RESPONSE_SERVICE_ERROR, "微信提交投诉回复异常V3");
} finally {
if (null != response) {
response.close();
}
httpClient.close();
}
if (null != response && (response.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT || response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)) {
logger.info("微信提交投诉回复成功V3 请求url={} ,body={} ", url,strBody);
} else {
logger.error("response:" + response.getEntity().toString());
logger.error("微信提交投诉回复失败V3 请求url={} ,body={} ,response={},失败code={}", url,strBody,response.toString(),response != null ? response.getStatusLine().getStatusCode():"response is null");
throw new ServiceException(Constant.API_RESPONSE_SERVICE_ERROR, "微信提交投诉回复失败V3 响应异常");
}
complaintMapper.updateComplaintState(submitComplaintDTO.getComplaintId(),submitComplaintDTO.getLastModifiedBy(),"PROCESSING");
}