public String postFileMultiPart(String data,Map<String, ContentBody> reqParam) throws IOException {
HttpPost httpPost = new HttpPost(
"https://api.mch.weixin.qq.com/v3/merchant/media/upload");
StringEntity strEntity = new StringEntity(
data, ContentType.create("application/json", "utf-8"));
httpPost.setEntity(strEntity);
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
for(Map.Entry<String,ContentBody> param : reqParam.entrySet()){
multipartEntityBuilder.addPart(param.getKey(), param.getValue());
}
HttpEntity reqEntity = multipartEntityBuilder.build();
httpPost.setEntity(reqEntity);
// httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Accept", "application/json");
CloseableHttpResponse response = httpClient.execute(httpPost);
assertTrue(response.getStatusLine().getStatusCode() != 401);
try {
HttpEntity entity2 = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity2);
if (entity2 != null) {
String res=EntityUtils.toString(entity2, Charset.forName("UTF-8"));
System.out.println(res);
return res;
}
} finally {
response.close();
}
return null;
}
public static void main(String[] args) {
try {
// WxHttpClient.getInstance().postNonRepeatableEntityTest();
File file = new File("D:\\HomeLogoA.png");
FileInputStream fileInputStream = new FileInputStream(file);
String hex = new DigestUtils("SHA-256").digestAsHex(file);
System.out.println(hex);
String localFileName = "E:/2.jpg";
String data = "{\n"
+ "\"filename\": \"HomeLogoA.png\",\n"
+ "\"sha256\": \"367a353ff0a7777f1a122dc9576460fbb662434d7f83d514f585df667b8a6015\"\n"
+ "}";
Map<String,ContentBody> reqParam = new HashMap<String,ContentBody>();
reqParam.put("meta", new StringBody(data, ContentType.APPLICATION_JSON));
reqParam.put("file", new FileBody(file));
WxHttpClient.getInstance().postFileMultiPart(data,reqParam);
// WxHttpClient.getInstance().postNonRepeatableEntityTest();
} catch (IOException e) {
e.printStackTrace();
}
}
"{"code":"SIGN_ERROR","detail":{"detail":{"issue":"sign not match"},"field":"signature","location":"authorization","sign_information":{"method":"POST","sign_message_length":185,"truncated_sign_message":"POST\n/v3/merchant/media/upload\n1585041402\ncVPpueKiBckXFwPpCOCoeQTPvIdPmy1Z\n{\n\"filen\n","url":"/v3/merchant/media/upload"}},"message":"[0xe9][0x94][0x99][0xe8][0xaf][0xaf][0xe7][0x9a][0x84][0xe7][0xad][0xbe][0xe5][0x90][0x8d][0xef][0xbc][0x8c][0xe9][0xaa][0x8c][0xe7][0xad][0xbe][0xe5][0xa4][0xb1][0xe8][0xb4][0xa5]"}"
401错误代码
参照这个写就行了。
public static void main(String[] args) { try { //商户号 String mchid = ""; //证书序列号 String serial_no = ""; //商户私钥(拷贝apiclient_key.pem文件里-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----之间的内容) String rsaPrivateKey = ""; //微信支付平台公钥 String rsaPublicKeyFile = ""; //时间戳 String timestamp = Long.toString(System.currentTimeMillis()/1000); //随机数 String nonce_str = "liujinliang8848"; //图片文件 String filePath = "";//文件路径 String boundary = ""; File file = new File(filePath); String filename = file.getName();//文件名 String fileSha256 = DigestUtils.sha256Hex(new FileInputStream(file));//文件sha256 //拼签名串 StringBuffer sb = new StringBuffer(); 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\":\""+filename+"\",\"sha256\":\""+fileSha256+"\"}").append("\n"); System.out.println("签名原串:"+sb.toString()); //计算签名 String sign = new String(Base64.encodeBase64(signRSA(sb.toString(),rsaPrivateKey))); System.out.println("签名sign值:"+sign); //拼装http头的Authorization内容 String authorization ="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchid+"\",nonce_str=\""+nonce_str+"\",signature=\""+sign+"\",timestamp=\""+timestamp+"\",serial_no=\""+serial_no+"\""; System.out.println("authorization值:"+authorization); //接口URL String url = "https://api.mch.weixin.qq.com/v3/merchant/media/upload"; CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); //设置头部 httpPost.addHeader("Charset", "UTF-8"); httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Content-Type", "multipart/form-data; boundary =" + boundary); httpPost.addHeader("Authorization", authorization); //创建MultipartEntityBuilder MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532); //设置boundary multipartEntityBuilder.setBoundary("boundary"); multipartEntityBuilder.setCharset(Charset.forName("UTF-8")); //设置meta内容 multipartEntityBuilder.addTextBody("meta", "{\"filename\":\""+filename+"\",\"sha256\":\""+fileSha256+"\"}", ContentType.APPLICATION_JSON); //设置图片内容 multipartEntityBuilder.addBinaryBody("file", file, ContentType.create("image/jpg"), filename); //放入内容 httpPost.setEntity(multipartEntityBuilder.build()); //获取返回内容 CloseableHttpResponse response = httpclient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); String rescontent = new String(InputStreamTOByte(httpEntity.getContent())); System.out.println("返回内容:" + rescontent); //获取返回的http header Header headers[] = response.getAllHeaders(); int i = 0; while (i < headers.length) { System.out.println(headers[i].getName() + ": " + headers[i].getValue()); i++; } //验证微信支付返回签名 String Wtimestamp = response.getHeaders("Wechatpay-Timestamp")[0].getValue(); String Wnonce = response.getHeaders("Wechatpay-Nonce")[0].getValue(); String Wsign = response.getHeaders("Wechatpay-Signature")[0].getValue(); //拼装待签名串 StringBuffer ss = new StringBuffer(); ss.append(Wtimestamp).append("\n"); ss.append(Wnonce).append("\n"); ss.append(rescontent).append("\n"); //验证签名 if(verifyRSA(ss.toString(), Base64.decodeBase64(Wsign.getBytes()), rsaPublicKeyFile)) { System.out.println("签名验证成功"); } else { System.out.println("签名验证失败"); } EntityUtils.consume(httpEntity); response.close(); } catch (Exception e) { System.out.println("发送POST请求异常!" + e); e.printStackTrace(); } } public static byte[] InputStreamTOByte(InputStream in) throws IOException { int BUFFER_SIZE = 4096; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] data = new byte[BUFFER_SIZE]; int count = -1; while((count = in.read(data,0,BUFFER_SIZE)) != -1) outStream.write(data, 0, count); data = null; byte[] outByte = outStream.toByteArray(); outStream.close(); return outByte; } public static byte[] signRSA(String data, String priKey) throws Exception { //签名的类型 Signature sign = Signature.getInstance("SHA256withRSA"); //读取商户私钥,该方法传入商户私钥证书的内容即可 byte[] keyBytes = Base64.decodeBase64(priKey); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); sign.initSign(privateKey); sign.update(data.getBytes("UTF-8")); return sign.sign(); } public static boolean verifyRSA(String data, byte[] sign, String pubKey) throws Exception{ if(data == null || sign == null || pubKey == null){ return false; } CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream(pubKey); Certificate c = cf.generateCertificate(in); in.close(); PublicKey publicKey = c.getPublicKey(); Signature signature = Signature.getInstance("SHA256WithRSA"); signature.initVerify(publicKey); signature.update(data.getBytes("UTF-8")); return signature.verify(sign); }