美文网首页Spring-BootSpring Boot
RestTemplate设置headers,访问https实现s

RestTemplate设置headers,访问https实现s

作者: _奔波儿灞_ | 来源:发表于2017-09-15 15:20 被阅读8859次

    在上一篇springboot学习记录之RestTemplate中,我们知道了:

    1. 如何创建RestTemplate实例
    2. 如何通过spring管理RestTemplate
    3. 如何使用RestTemplate。

    在这篇文章中我们将重点说下如何来用https实现ssl请求。

    应用场景:微信支付之企业付款接口

    文档中提到:请求需要双向证书。 详见证书使用

    微信给我们颁发了pfx证书:apiclient_cert.p12

    这个时候我们不能像往常一样直接通过

    RestTemplate restTemplate = new RestTemplate();
    restTemplate.postForObject(url,T.class);
    

    来实现请求并获得结果,我们需要设置ssl相关信息及参数。

    微信官方实例:

    这个版本是基于httpcomponents 4.3.1 。pom 文件如下:

    
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.3.1</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
    
        private String ssl(String url, String data) {
    
            //HttpsRequest
            StringBuffer message = new StringBuffer();
            try {
                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                FileInputStream instream = new FileInputStream(new File("证书地址"));
                keyStore.load(instream, "支付商户号".toCharArray());
                // Trust own CA and all self-signed certs
                SSLContext sslcontext = SSLContexts.custom()
                        .loadKeyMaterial(keyStore, "支付商户号".toCharArray())
                        .build();
                // Allow TLSv1 protocol only
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslcontext,
                        new String[]{"TLSv1"},
                        null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
                CloseableHttpClient httpclient = HttpClients.custom()
                        .setSSLSocketFactory(sslsf)
                        .build();
                HttpPost httpost = new HttpPost(url);
    
                httpost.addHeader("Connection", "keep-alive");
                httpost.addHeader("Accept", "*/*");
                httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
                httpost.addHeader("Host", "api.mch.weixin.qq.com");
                httpost.addHeader("X-Requested-With", "XMLHttpRequest");
                httpost.addHeader("Cache-Control", "max-age=0");
                httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
                httpost.setEntity(new StringEntity(data, "UTF-8"));
               
    
                CloseableHttpResponse response = httpclient.execute(httpost);
                try {
                    HttpEntity entity = response.getEntity();
    
                    if (entity != null) {
                    
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
                        String text;
                        while ((text = bufferedReader.readLine()) != null) {
                            message.append(text);
                        }
                    }
                    EntityUtils.consume(entity);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    response.close();
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
    
            return message.toString();
        }
    
    

    那么我们如何用RestTemplate 来实现呢:
    我这边使用的是httpcomponents 最新版4.5.3:

        <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.3</version>
            </dependency>
    
    

    构建httpclient参数的时候有些和4.3.1不同

    
        public String TransferRestTemplate(String url,String data) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(merchantInfo.getPfx()));
            keyStore.load(instream, merchantInfo.getId().toCharArray());
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContextBuilder.create()
                    .loadKeyMaterial(keyStore, merchantInfo.getId().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; charset=UTF-8");
            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) ");
    
            org.springframework.http.HttpEntity<String> requestEntity =
                    new  org.springframework.http.HttpEntity(new StringEntity(data, "UTF-8"),requestHeaders);
    
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
            String sttr = response.getBody();
            return sttr;
    
        }
    

    注意:此处HttpEntity 和上面的微信实例的org.apache.http.HttpEntity 是不同的。

    这样我们就实现了ssl请求了。

    相关文章

      网友评论

        本文标题:RestTemplate设置headers,访问https实现s

        本文链接:https://www.haomeiwen.com/subject/fegssxtx.html