使用服务商/点商品平台v3文件上传接口时,返回的一直是400,且没有任何错误代码
发起方法
public String partnerMediaUpload(MultipartFile file1) throws IOException {
// 构建uri
URI uri = buildPartnerUpdateURI();
// 创建post请求
HttpPost httpPost = new HttpPost();
// 使用演示的文件
File file = new File("D:\\temp\\afa3b3dc1bc087324cb264b747dcffc.jpg");
// 文件名称以及后缀
String fileName = file.getName();
String fileSuffixName = FileUtils.getFileSuffixName(fileName);
// sha256计算
String sha256;
try {
InputStream inputStream = Files.newInputStream(file.toPath());
sha256 = DigestUtils.sha256Hex(inputStream);
inputStream.close();
} catch (IOException e) {
logger.error("将图片进行二进制进行sha256失败!错误信息为:{}", e.getMessage());
throw new ServiceException("上传文件失败!");
}
// meta信息
Map<String, String> metaParam = new HashMap<>();
metaParam.put("filename", fileName);
metaParam.put("sha256", sha256);
String metaJsonStr = JSON.toJSONString(metaParam);
// 构建请求body
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder
.setBoundary(BOUNDARY)
.setMode(HttpMultipartMode.RFC6532)
.addTextBody("meta", metaJsonStr, ContentType.APPLICATION_JSON)
.addBinaryBody("file", Files.newInputStream(file.toPath()), ContentType.create(MIMEUtils.ofMimeType(fileSuffixName)), fileName);
HttpEntity entity = entityBuilder.build();
// 生成签名
WxSignResultDetailDTO signDetail;
try {
signDetail = WxPayUtils.sign(httpPost, WxPayUrlPathConstant.PARTNER_MERCHANT_MEDIA_UPLOAD, metaJsonStr, wxPayHttpClient.buildPrivateKey());
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
logger.error("生成微信图片签名失败!错误信息为:{}", e.getMessage());
throw new ServiceException("上传文件失败!");
}
// 构建请求头参数
String contentType = "multipart/form-data;boundary=" + BOUNDARY;
String authorization = "WECHATPAY2-SHA256-RSA2048 " +
"mchid=\"" + wxPayConfig.getMerchantId() + "\","
+ "nonce_str=\"" + signDetail.getNonceStr() + "\","
+ "timestamp=\"" + signDetail.getTimestamp() + "\","
+ "serial_no=\"" + wxPayConfig.getMerchantSerialNumber() + "\","
+ "signature=\"" + signDetail.getSignature() + "\"";
// 添加请求参数
httpPost.setURI(uri);
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", contentType);
httpPost.setHeader("Authorization", authorization);
// 发送请求
WxRes<WxPartnerMediaUploadRes> uploadRes = wxPayHttpClient.execute(httpPost, WxPartnerMediaUploadRes.class);
if (!Objects.equals(Boolean.TRUE, uploadRes.getSuccess())) {
logger.error("发送微信上传图片请求失败 !请求地址为:{},错误信息为{}", WxPayUrlPathConstant.PARTNER_MERCHANT_MEDIA_UPLOAD, uploadRes.getErrMsg());
throw new ServiceException("上传失败!");
}
return uploadRes.getData().getMedia_id();
}
签名方法
public static WxSignResultDetailDTO sign(HttpRequestBase request,
String url,
String paramsStr,
PrivateKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
// 生成一个随机数(这里使用uuid)
String nonceStr = UUID.randomUUID().toString().replace("-", "");
// 当前时间戳(按秒)
long timestamp = System.currentTimeMillis() / 1000;
// 需要签名的字符串
String message =
request.getMethod() + "\n"
+ url + "\n"
+ timestamp + "\n"
+ nonceStr + "\n"
+ paramsStr + "\n";
// 进行签名
String sign = sign(message.getBytes(StandardCharsets.UTF_8), privateKey);
// 封装参数
WxSignResultDetailDTO result = new WxSignResultDetailDTO();
result.setNonceStr(nonceStr);
result.setTimestamp(String.valueOf(timestamp));
result.setSignature(sign);
return result;
}
private static String sign(byte[] message, PrivateKey privateKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException {
// 创建一个签名对象
Signature sign = Signature.getInstance("SHA256withRSA");
// 初始化私钥
sign.initSign(privateKey);
// 添加消息体
sign.update(message);
// 生成签名
return Base64.getEncoder().encodeToString(sign.sign());
}
debug的信息:
Authorization: WECHATPAY2-SHA256-RSA2048 mchid="********",nonce_str="66f55f5a69e843fd94a04e8e9677d9b7",timestamp="1689132016",serial_no="***************************",signature="0oS5i68DJTzVUhctKYEaoXPRUkPfPK9tSMYivIxTKGFBg7SLAAegHVhM6wvGYhH/oyZGTniaP0agcZG8S8+MkyXRP3qgMKaauC1b3uqwSJBMq7gZJRoS6RmUfG9jUgu+gf3OZJNbRGoQqe6IbDHu6EGXGW0pNFr+BkRBWyFJGjGOv+XvzAyx/+Os3BJc0NrnFtvmyXVoS0V1bjVcd9rJgK9pkmkQ9c+8ehq7ocvsvmkWgfKiBVymhiNICdjkevjjGZrHQGsjj8oyiPMSY8IDb5F7udjIVYRGXqNY/MGWetnVgHsW7ZpCCgmHxchx2mSPUjdB0dJFdfRpESzDwP4urQ=="
错误信息为:
11:23:29.283 [http-nio-9207-exec-3] ERROR c.w.p.c.a.h.SignatureExec - [executeWithSignature,95] - 应答的状态码不为200-299。status code[400] request headers[[Content-Type: multipart/form-data;boundary=mengchongtech, Authorization: WECHATPAY2-SHA256-RSA2048 mchid="******",nonce_str="66f55f5a69e843fd94a04e8e9677d9b7",timestamp="1689132016",serial_no="***********************",signature="0oS5i68DJTzVUhctKYEaoXPRUkPfPK9tSMYivIxTKGFBg7SLAAegHVhM6wvGYhH/oyZGTniaP0agcZG8S8+MkyXRP3qgMKaauC1b3uqwSJBMq7gZJRoS6RmUfG9jUgu+gf3OZJNbRGoQqe6IbDHu6EGXGW0pNFr+BkRBWyFJGjGOv+XvzAyx/+Os3BJc0NrnFtvmyXVoS0V1bjVcd9rJgK9pkmkQ9c+8ehq7ocvsvmkWgfKiBVymhiNICdjkevjjGZrHQGsjj8oyiPMSY8IDb5F7udjIVYRGXqNY/MGWetnVgHsW7ZpCCgmHxchx2mSPUjdB0dJFdfRpESzDwP4urQ==", Accept: application/json, Authorization: WECHATPAY2-SHA256-RSA2048 mchid="********",nonce_str="4FlV9Blikk8d42Yyj96VclRqVLRvbPu0",timestamp="1689132209",serial_no="*****************",signature="gFOocuO5z2o7gPlW/ZJj9PRp9XHVH4VQ40kcn/EA6DwXsiMRMFCSjZecJ6t/ob/U5+zinLgzFj+uX7VJOzefrz/N1+NktdDzYB/tGHpiFKqYVdtCBXziOMDuePM+ydx4uyN5rObHdpYYkK4qIW5RRAL/WYm+sgguHQ4moYDppWVj8Cyx/QP6JShAHFkYkfYRW3RV9TaOxcQdC84u1A+HLXODAPHf0csTTYzQvVdJ9NbJJLHzzojLIY9lcor7TJldK8yxV1E+MT5mjC1JIh3KxLgY7MSE0UQsEaLx0eAeqe0YkiaAoGMM7vMrVL6ezmTcAXEpToXwivUnAGisHV6hGg==", Content-Length: 193679, Host: api.mch.weixin.qq.com, Connection: Keep-Alive, User-Agent: WechatPay-Apache-HttpClient/0.4.8 (Windows 10/10.0) Java/1.8.0_202, Accept-Encoding: gzip,deflate]]
11:23:29.285 [http-nio-9207-exec-3] ERROR c.w.p.c.a.h.SignatureExec - [executeWithSignature,100] - 应答的状态码不为200-299。request body
[--mengchongtech
Content-Disposition: form-data; name="meta"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{"filename":"afa3b3dc1bc087324cb264b747dcffc.jpg","sha256":"1f03585317885cc1603cb28fa4ab07bcd272b3f2508594406d89177226ce6305"}
--mengchongtech
Content-Disposition: form-data; name="file"; filename="afa3b3dc1bc087324cb264b747dcffc.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
ÿØÿà JFIF ÿÛ C #,%!*!&4'*./121%6:60:,010ÿÛ C
0 00000000000000000000000000000000000000000000000000ÿÀ ä" ÿÄ
……文件二进制流
.
.
.
.
,qF¡`* KEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPÿÙÐ; Æ
Êó}NQü¢ìf/
--mengchongtech--
]
一直找不到错误,麻烦看一下错误在哪里。
问题找到了,上述代码没有任何问题。问题在于
的方法上。这里是我对微信官方的工具进行了二次封装,可能这个工具类也进行了二次签名还是啥的。然后可能把里面参数搞错了。看错误信息中有head中有两个签名数据,之前一直没注意,所以问题大概率也在这里。最后将
换为普通的httpClient即可
CloseableHttpClient httpClient = HttpClientBuilder.create().build(); CloseableHttpResponse res = httpClient.execute(httpPost);
你好,请先参考这个帖子看看是否能解决您的问题
https://developers.weixin.qq.com/community/develop/doc/000c46e5004088a0dd3b5bbed51400?_at=1614235075250