zoukankan      html  css  js  c++  java
  • springboot 使用 RestTemplate 携带 微信API证书发送请求实现企业付款到零钱/提现/微信退款等场景

    springboot版本:

    2.2.0.BUILD-SNAPSHOT

    可使用场景:企业付款到零钱/提现/微信退款等场景

    企业提现零钱付款场景下:

    下面是能跑通的代码,减少踩坑时间.

    两套方案:一套使用注入bean的方式:

    ("商户号".toCharArray(),商户号就是证书密码)

    @Configuration
    public class RestTemplateCert {
    
        @Qualifier("RestTemplateWithCert")
        @Bean
        public RestTemplate getRestTemplateWithCert() {
    
            RestTemplate restTemplate = null;
            try {
                KeyStore keyStore = KeyStore.getInstance("PKCS12");//eg. PKCS12
    //            这个之前尝试放在resources目录下来读取,结果这个居然是证书错误的源头,使用下面的直接从路径读取就能成功了,证书读取有问题spring没有报错,大坑
    //            InputStream cp = this.getClass().getResourceAsStream("apiclient_cert.p12");
                FileInputStream instream = new FileInputStream(new File("C:\extend\apiclient_cert.p12"));
                keyStore.load(instream, "商户号".toCharArray());
                // Trust own CA and all self-signed certs
                SSLContext sslcontext = SSLContextBuilder.create()
                        .loadKeyMaterial(keyStore, "商户号".toCharArray())
                        .build();
                // Allow TLSv1 protocol only
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, NoopHostnameVerifier.INSTANCE);
                CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
                HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
                restTemplate = new RestTemplate(factory);
                //将转换器的编码换成utf-8
                restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("utf-8")));
                //System.out.println("restTemplate.hashCode():" + restTemplate.hashCode());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return restTemplate;
        }
    
        @Primary
        @Bean
        public RestTemplate getRestTemplate() {
            RestTemplate restTemplate = new RestTemplate();
    
            //将转换器的编码换成utf-8
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("utf-8")));
            return restTemplate;
        }
    
    }
    携带微信api证书:
        @Qualifier("RestTemplateWithCert")
        @Resource
        private RestTemplate restTemplateWithCert;
    
    常规请求:
        @Resource
        private RestTemplate restTemplate;

    微信提现请求:

         HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            String body = "xml数据";
            String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
            HttpEntity<String> request = new HttpEntity<>(body, headers);
            ResponseEntity<String> res = restTemplateWithCert.postForEntity(url, request, String.class);
            System.out.println(res.getBody());

    第二个解决方案:

    需要依赖:

            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.3</version>
            </dependency>
    public class WxSSLTestTemplate {
    
        public static String TransferRestTemplate(String url, String data) throws KeyStoreException, IOException, UnrecoverableKeyException, KeyManagementException, CertificateException, NoSuchAlgorithmException {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File("C:\extend\apiclient_cert.p12"));
            keyStore.load(instream, "商户号".toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContextBuilder.create()
                    .loadKeyMaterial(keyStore, "商户号".toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"},
                    null, hostnameVerifier);
    
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
    
            HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
            RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.add("Connection", "keep-alive");
            requestHeaders.add("Accept", "*/*");
            requestHeaders.add("Content-Type", "application/x-www-form-urlencoded");
            requestHeaders.add("Host", "api.mch.weixin.qq.com");
            requestHeaders.add("X-Requested-With", "XMLHttpRequest");
            requestHeaders.add("Cache-Control", "max-age=0");
            requestHeaders.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
    
    //        如果使用这个方法,就不能使用下面的这个实例化,而要使用下面第一条使用中的request,否则会报jackson的错误,就算配置忽略bean的检测也没用
    //        org.springframework.http.HttpEntity<String> requestEntity =
    //                new org.springframework.http.HttpEntity(new StringEntity(data, "UTF-8"), requestHeaders);
    
            HttpEntity<String> request = new HttpEntity<>(data, requestHeaders);
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);
            return response.getBody();
        }
    
    }

    微信提现请求:

            String body = "xml数据";
            String url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
            String result = WxSSLTestTemplate.TransferRestTemplate(url, body);
            System.out.println(result);

    这样就可以完美跑通了

  • 相关阅读:
    [洛谷P2824][题解][HEOI2016/TJOI2016]排序
    [整理]CSP-S2019第一轮试题解析
    [整理]Luogu CSP2020第一轮模拟赛
    [洛谷P4395][题解][BOI2003]Gem 气垫车
    [洛谷P5322][BJOI2019][题解]排兵布阵
    [整理]U S A C O 代 码 小 合 集
    第02组Alpha冲刺 总结
    第02组 Alpha冲刺 (6/6)
    第02组 Alpha冲刺 (5/6)
    第02组 Alpha冲刺 (4/6)
  • 原文地址:https://www.cnblogs.com/kinome/p/12684994.html
Copyright © 2011-2022 走看看