微信支付/服务商上传图片获取 media_id

不废话直接上代码。
需要配置商户号、商户秘钥、商户证书

需要使用的pom

   <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>4.5.8</version>
   </dependency>

代码


import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;
import java.util.UUID;

/**
 * @program: Controller
 * @description:
 * @author: 云晓得峰
 * @create: 2022/9/28 10:46
 */
@Api(description = "上传")
@RestController
@RequestMapping("/api/")
public class Controller {

    @ApiOperation(value = "图片上传")
    @ApiResponses(value = {
            @ApiResponse(code = 0000, message = "请求已完成"),
            @ApiResponse(code = 0001, message = "操作失败"),
    })
    @ApiImplicitParams({
            @ApiImplicitParam(value = "(必传)token", name = "token", dataType = "String", required = true, paramType = "header"),
    })
    @PostMapping(value = "/addimg" , produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String addimg(@RequestParam("file") MultipartFile file ) throws Exception {
        String mediaid=null;
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        String filename = file.getOriginalFilename();
        String suffix = filename.substring(filename.lastIndexOf(".") + 1);
        filename = uuid + "."+suffix ;
        if (file!=null) {
            if (!"".equals(filename.trim())) {
                //商户号
                String mch_id="";
                //商户key
                String appKey="";
                Map<String, String> stringStringMap = UploadServiceImpl.wxImageUpload(file, mch_id, appKey);
                if(stringStringMap!=null && stringStringMap.get("return_msg").equals("OK")
                        && stringStringMap.get("result_code").equals("SUCCESS") && stringStringMap.get("return_code").equals("SUCCESS")){
                    mediaid  = stringStringMap.get("media_id").toString();
                }else {
                    return  "";
                }
            }
        }
        return mediaid;

    }
}

import org.apache.commons.codec.binary.Hex;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: UploadServiceImpl
 * @description:
 * @author: 云晓得峰
 * @create: 2022/9/28 10:49
 */
public class UploadServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(UploadServiceImpl.class);
    /**
     * 【需要设置】
     登录微信商户平台
     账户中心-》API安全-》申请API证书-》API证书管理
     */
      private final static String wechatKeyFile = "C:/cert/apiclient_cert.p12";
    /**
     * 上传时调用此方法
     * @param file 文件流
     * @param mch_id 商户号
     * @param appKey 商户key
     */
    public static Map<String, String> wxImageUpload(MultipartFile file, String mch_id, String appKey) {

        try {
            byte [] byteArr=file.getBytes();
            InputStream inputStream = new ByteArrayInputStream(byteArr);
            String media_hash = md5HashCode(file.getInputStream());

            Map paramMap = new HashMap<>();//用来参与计算sign的参数

            paramMap.put("mch_id", mch_id);

            paramMap.put("media_hash", media_hash);

            paramMap.put("sign_type", "HMAC-SHA256");

            String sign = sha256Sign(paramMap, appKey);

            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();//用来实际请求接口的参数
            multipartEntityBuilder.addTextBody("mch_id", mch_id, ContentType.MULTIPART_FORM_DATA);
            multipartEntityBuilder.addBinaryBody("media", inputStream, ContentType.create("image/jpg"),  file.getOriginalFilename());
            multipartEntityBuilder.addTextBody("media_hash", media_hash, ContentType.MULTIPART_FORM_DATA);
            multipartEntityBuilder.addTextBody("sign_type", "HMAC-SHA256", ContentType.MULTIPART_FORM_DATA);
            multipartEntityBuilder.addTextBody("sign", sign, ContentType.MULTIPART_FORM_DATA);
            FileInputStream instream = null;
            SSLContext sslcontext = null;
            try {
                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                instream = new FileInputStream(new File(wechatKeyFile));
                keyStore.load(instream, mch_id.toCharArray());// 这里写密码..默认是你的MCHID
                sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build();
            } catch (Exception e) {
                logger.error("证书加载失败!{}", e);
            } finally {
                try {
                    if (instream != null) {
                        instream.close();
                    }
                } catch (IOException e) {
                    logger.error("证书加载失败!{}", e);
                }
            }

            @SuppressWarnings("deprecation")
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            try {

                HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/secapi/mch/uploadmedia");
                RequestConfig config = RequestConfig.custom().setConnectTimeout(10000).setConnectionRequestTimeout(10000).setSocketTimeout(10000).build();

                httpPost.setConfig(config);

                httpPost.addHeader("Content-Type", "multipart/form-data; charset=UTF-8");

                httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36");

                httpPost.setEntity(multipartEntityBuilder.build());

                CloseableHttpResponse response = httpclient.execute(httpPost);

                String result = EntityUtils.toString(response.getEntity(), "UTF-8");
                Map<String, String> resMap =  xmlStrToMap(result);
                return  resMap;
            } catch (Exception e) {

                logger.error("请求失败!{}", e);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }
        return  null;
    }
    /**
     * Xml字符串转换为Map
     *
     * @return
     */
    public static Map<String,String> xmlStrToMap(String strXML) throws IOException, SAXException, ParserConfigurationException {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilder documentBuilder =  newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            logger.error("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }

    }
    public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
        documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
        documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        documentBuilderFactory.setXIncludeAware(false);
        documentBuilderFactory.setExpandEntityReferences(false);

        return documentBuilderFactory.newDocumentBuilder();
    }

    /**

     * 对上次文件进行MD5获取其Hash值

     *

     * @param fis

     * @return

     */

    public static String md5HashCode(InputStream fis) {

        try {

            MessageDigest MD5 = MessageDigest.getInstance("MD5");

            byte[] buffer = new byte[8192];

            int length;

            while ((length = fis.read(buffer)) != -1) {

                MD5.update(buffer, 0, length);

            }

            return new String(Hex.encodeHex(MD5.digest()));

        } catch (Exception e) {

            e.printStackTrace();

            return null;

        }

    }

    /**

     * 获取HMAC-SHA256签名

     *

     * @param paramMap 签名参数(sign不参与签名)

     * @param key 签名密钥

     * @return HMAC-SHA256签名结果

     */

    public final static String sha256Sign(Map paramMap, String key) {

        try {

            String payParam = getSignTemp(paramMap, key);

            logger.info("签名原文:{}", payParam);

            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");

            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");

            sha256_HMAC.init(secret_key);

            byte[] array = sha256_HMAC.doFinal(payParam.getBytes("UTF-8"));

            StringBuilder sb = new StringBuilder();

            for (byte item : array) {

                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));

            }

            String sign = sb.toString().toUpperCase();

            logger.info("签名结果:{}", sign);

            return sign;

        } catch (Exception e) {

            return null;

        }

    }

    /**

     * 获取签名参数字符串

     *

     * @param paramMap 签名参数(sign字段不参与签名)

     * @param payKey 签名密钥

     * @return 待签名字符串

     */

    private final static String getSignTemp(Map paramMap, String payKey) {

        ArrayList keyList = new ArrayList<>(paramMap.keySet());

        Collections.sort(keyList);

        StringBuilder signParam = new StringBuilder();

        for (Object key : keyList) {

            if (!"sign".equals(key) && paramMap.get(key) != null) {

                signParam.append(key).append("=").append(paramMap.get(key)).append("&");

            }

        }

        signParam.delete(signParam.length() - 1, signParam.length());

        signParam.append("&key=").append(payKey);

        return signParam.toString();

    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白菜S

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值