1. 程式人生 > 其它 >SpringBoot 微信支付V3介面圖片上傳工具類

SpringBoot 微信支付V3介面圖片上傳工具類

技術標籤:javajava

微信V3介面 圖片上傳API

準備一個V3介面Token生成工具

package com.youjia.datacenter.base.util.pay.wxPay;

import com.youjia.datacenter.util.RandomUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.Signature; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; public class WxV3TokenUtil { private final static Logger logger = LoggerFactory.getLogger(WxV3TokenUtil.class
); public static String getToken(String method, String url, String body) throws Exception { String nonceStr = RandomUtil.str_(32); long timestamp = System.currentTimeMillis() / 1000; String message = buildMessage(method, url, timestamp, nonceStr, body); String signature =
sign(message.getBytes("UTF-8")); return "mchid=\"" + WxConfig.INSTANCE.getMchId() + "\"," + "nonce_str=\"" + nonceStr + "\"," + "timestamp=\"" + timestamp + "\"," + "serial_no=\"" + WxConfig.INSTANCE.getApiCertSerialNumber() + "\"," + "signature=\"" + signature + "\""; } private static String sign(byte[] message) throws Exception { Signature sign = Signature.getInstance("SHA256withRSA"); sign.initSign(getPrivateKey()); sign.update(message); return Base64.getEncoder().encodeToString(sign.sign()); } private static String buildMessage(String method, String url, long timestamp, String nonceStr, String body) throws Exception{ return method + "\n" + url + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n"; } private static PrivateKey getPrivateKey() throws IOException { //privateKeyData 是微信支付證書中的 apiclient_key.pem String content = new String(WxConfig.INSTANCE.getPrivateKeyData(), "UTF-8"); try { String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s+", ""); logger.info("privateKey:" + privateKey); KeyFactory kf = KeyFactory.getInstance("RSA"); return kf.generatePrivate( new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey))); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("當前Java環境不支援RSA", e); } catch (InvalidKeySpecException e) { logger.info("異常:" + e); throw new RuntimeException("無效的金鑰格式"); } } }

編寫上傳工具

package com.youjia.datacenter.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.youjia.datacenter.base.config.SysConfig.MpConstants;
import com.youjia.datacenter.base.util.pay.wxPay.WxConfig;
import com.youjia.datacenter.base.util.pay.wxPay.WxV3TokenUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.StringBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class WxMediaUploadUtil {
    private final static Logger logger = LoggerFactory.getLogger(WxMediaUploadUtil.class);
    /**
     * 上傳圖片檔案至微信伺服器
     * @param fileName
     * @Param filePath
     * @return 微信mediaId
     */
    public static String uploadMediaFile(String fileName,String filePath){
        if(StringUtils.isBlank(filePath)){
            return null;
        }
        File file = new File(filePath);
        if(!file.exists()){
            return null;
        }
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            String sha256 = DigestUtils.sha256Hex(fileInputStream);
            String url = MpConstants.WX_UPLOAD_FILE_URL;
            String signUrl = url.replace("https://api.mch.weixin.qq.com","");

            //根屬性
            JSONObject root = new JSONObject();

            //mate
            JSONObject meta = new JSONObject();
            meta.put("filename",fileName);
            meta.put("sha256",sha256);
            String json = root.toJSONString();
            //獲取簽名字串
            String sign = WxV3TokenUtil.getToken("POST",signUrl,meta.toJSONString());
            Map<String,String> headers = new HashMap<>();
            String authorization  = "WECHATPAY2-SHA256-RSA2048 "+sign;
            headers.put("Authorization",authorization);
            headers.put("Content-Type","multipart/form-data");
            headers.put("Accept", "application/json");
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().addBinaryBody("file",file).addPart("meta",new StringBody(meta.toJSONString(),ContentType.APPLICATION_JSON)).setContentType(ContentType.MULTIPART_FORM_DATA);
            String res = HttpUtils.httpsPostFile(url,multipartEntityBuilder,headers);
            logger.info(">>>>>提交微信圖片 res={"+res+"}");
            JSONObject result = JSON.parseObject(res);
            if(result.containsKey("media_id")){
                return result.getString("media_id");
            }
            logger.error(">>>>>上傳檔案到微信未成功,res={"+res+"}");
            return null;
        } catch (Exception e) {
            logger.error(">>>>>上傳圖片到微信出現錯誤",e);
        }finally {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                logger.error(">>>>>>");
            }
        }
        return null;
    }
}

程式碼中使用的HttpUtils

此工具類在此部落格 HttpUtils

將此方法新增至HttpUtils中

public static String httpsPostFile(String url, MultipartEntityBuilder multipartEntityBuilder,Map<String,String> headers) throws Exception {
        CloseableHttpClient hp = createSSLClientDefault();
        HttpPost httpPost = new HttpPost(url);
        Iterator<Map.Entry<String, String>> iterator = headers.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            httpPost.setHeader(entry.getKey(), entry.getValue());
        }
        //httpPost.setHeader("Content-Type","application/json");
        multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        HttpEntity httpEntity = multipartEntityBuilder.build();
        httpPost.setEntity(httpEntity);
        CloseableHttpResponse response = hp.execute(httpPost);
        HttpEntity entity = response.getEntity();
        String content = EntityUtils.toString(entity, "UTF-8");
        hp.close();
        return content;
    }

測試

在這裡插入圖片描述
在這裡插入圖片描述
打印出微信返回的media_id