v3图片上传接口java代码(httpclient和httpmime实现)
之前用HttpURLConnection实现的,现在改成用httpclient和httpmime实现(我用的是4.5.9版本),感觉会简单一点。水平有限,如有错误请指正。 [代码]public[代码] [代码]class[代码] [代码]uploadFileTest2 {[代码] [代码] [代码][代码]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 = [代码][代码]""[代码][代码];[代码][代码] [代码] [代码] [代码][代码]//图片文件[代码][代码] [代码][代码]String filePath = [代码][代码]""[代码][代码];[代码][代码]//文件路径[代码][代码] [代码][代码]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([代码][代码]"Accept"[代码][代码], [代码][代码]"application/json"[代码][代码]);[代码][代码] [代码][代码]httpPost.addHeader([代码][代码]"Content-Type"[代码][代码], [代码][代码]"multipart/form-data"[代码][代码]);[代码][代码] [代码][代码]httpPost.addHeader([代码][代码]"Authorization"[代码][代码], authorization);[代码][代码] [代码] [代码] [代码][代码]//创建MultipartEntityBuilder [代码][代码] [代码][代码]MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create()[代码].setMode(HttpMultipartMode.RFC6532);[代码] [代码][代码]//设置boundary[代码][代码] [代码][代码]multipartEntityBuilder.setBoundary([代码][代码]""[代码][代码]);[代码][代码] [代码][代码]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); } [代码][代码] [代码] [代码] [代码]}[代码]