V3图片上传可以使用wechatpay-apache-httpclient吗?
发布于 6 年前 作者 xiuying51 2005 次浏览 来自 官方Issues

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();
		}
	}
}

图片上传 签名始终过不去 加下微信 给看看呗 谢谢啊 18226605357

同问,今天正在弄这个,记录一下。

回到顶部