V3图片上传可以使用wechatpay-apache-httpclient吗?
ApiV3图片上传接口可以使用wechatpay-apache-httpclient吗?
3 回复
public String postMediaUpload(String merchantId,String filePath,String fileDesc) throws Exception {
DataOutputStream dos = null;
InputStream is = null;
try {
PrivateKey privateKey = ;
// 换行符
String lineSeparator = "\r\n";//不能使用System.lineSeparator(),linux环境微信会报验签失败
String boundary = "boundary";
String beforeBoundary = "--";//必须为--
//时间戳
String timestamp = Long.toString(System.currentTimeMillis()/1000);
//随机数
String nonce_str = UUID.randomUUID().toString().replaceAll("-","");
File file = new File(filePath);
String filename = file.getName();//文件名
is = new FileInputStream(file);
String fileSha256 = DigestUtils.sha256Hex(is);//文件sha256值
is.close();
//拼签名串
StringBuilder sb = new StringBuilder();//签名的串
sb.append("POST").append("\n");
sb.append("/v3/merchant/media/upload").append("\n");
sb.append(timestamp).append("\n");
sb.append(nonce_str).append("\n");
sb.append("{\"filename\":\"").append(filename).append("\",\"sha256\":\"").append(fileSha256).append("\"}").append("\n");
log.info("签名的串:"+sb.toString());
byte[] bytes = sb.toString().getBytes("utf-8");
log.info("签名的串的字节长度:{}",bytes.length);
//计算签名
String sign = sign(bytes,privateKey);
log.info("签名sign值:"+sign);
//拼装http头的Authorization内容
String authorization =schema + " mchid=\""+merchantId
+"\",nonce_str=\""+nonce_str
+"\",signature=\""+sign
+"\",timestamp=\""+timestamp
+"\",serial_no=\""+wxPayV3ApiPrivateKey.getSerialNumber()+"\"";
log.info("authorization值:"+authorization);
//接口URL
URL url = new URL(baseUrl()+"merchant/media/upload");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置为POST
conn.setRequestMethod("POST");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求头参数
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.setRequestProperty("Authorization", authorization);
dos = new DataOutputStream(conn.getOutputStream());
//拼装请求内容第一部分
String metaPart = beforeBoundary + boundary + lineSeparator +
"Content-Disposition: form-data; name=\"meta\";" + lineSeparator +
"Content-Type: application/json" + lineSeparator +
lineSeparator +//必须有
"{\"filename\":\"" + filename + "\",\"sha256\":\"" + fileSha256 + "\"}" + lineSeparator;
dos.writeBytes(metaPart);
dos.flush();
//拼装请求内容第二部分
String filePart = beforeBoundary + boundary + lineSeparator +
"Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\";" + lineSeparator +
"Content-Type: image/jpeg" + lineSeparator +
lineSeparator;//必须有
dos.writeBytes(filePart);
dos.flush();
//文件二进制内容
byte[] buffer = new byte[1024];
int len;
is = new FileInputStream(file);
while ((len = is.read(buffer)) != -1){
dos.write(buffer,0,len);
dos.flush();//不需要写完整个文件+尾行后再flush
}
is.close();
//拼装请求内容结尾
String endLine = lineSeparator
+ beforeBoundary
+ boundary
+ "--" //必须,标识请求体结束
+ lineSeparator;
dos.writeBytes(endLine);
dos.flush();
dos.close();
//接收返回
//打印返回头信息
StringBuilder respHeaders = new StringBuilder();
Map<String, List<String>> responseHeader = conn.getHeaderFields();
for (Map.Entry<String, List<String>> entry : responseHeader.entrySet()) {
respHeaders.append(lineSeparator).append(entry.getKey()).append(":").append(entry.getValue());
}
log.info("微信应答的头信息:{}",respHeaders);
//打印返回内容
int responseCode = conn.getResponseCode();
String rescontent;//应答报文主体
if((responseCode+"").equals("200")){
rescontent = new String(inputStreamToByteArray(conn.getInputStream()),"utf-8");
log.info("图片上传成功,微信应答:"+ rescontent);
//验证微信支付返回签名
String wechatPayTimestamp = responseHeader.get("Wechatpay-Timestamp").get(0);
String wechatPayNonce = responseHeader.get("Wechatpay-Nonce").get(0);
String wechatPaySignature = responseHeader.get("Wechatpay-Signature").get(0);
String wechatPaySerial = responseHeader.get("Wechatpay-Serial").get(0);
//拼装待签名的串
//验证签名
String respSignedStr = wechatPayTimestamp + "\n" +
wechatPayNonce + "\n" +
rescontent + "\n";
X509Certificate cert = wxX509Certificates.get(merchantId).getCert(wechatPaySerial);
if(verify(respSignedStr,wechatPaySignature,cert)) {
log.info("验签通过");
return JSONObject.parseObject(rescontent).getString("media_id");
} else {
log.error("验签未通过,被签名串=[{}],微信签名=[{}],验签证书=[{}]",respSignedStr,wechatPaySignature,cert);
throw new FapSysException(FAPExcConst.FAIL_CHANNEL.getCode(),"微信图片上传接口应答报文验签未通过"+"["+fileDesc+"]");
}
}else{
rescontent = new String(inputStreamToByteArray(conn.getErrorStream()),"utf-8");
log.info("图片上传失败,微信应答:"+rescontent);
//失败处理
JSONObject respJSONObject = null;
try {
respJSONObject = JSONObject.parseObject(rescontent);
}catch (Exception e){
log.error("JSONObject.parseObject Exception",e);
}
if (respJSONObject!=null&&respJSONObject.get("message")!=null){
throw new RuntimeException(respJSONObject.getString("message")+"["+fileDesc+"]");
}else {
throw new RuntimeException("微信图片上传接口应答HTTP状态码不为200"+"["+fileDesc+"]");
}
}
}finally {
if (is!=null){
is.close();
}
if (dos!=null){
dos.close();
}
}
}