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(); } } }
V3图片上传可以使用wechatpay-apache-httpclient吗?ApiV3图片上传接口可以使用wechatpay-apache-httpclient吗?
2019-12-25