Java調用Http/Https接口(6)--RestTemplate調用Http/Https接口


RestTemplate是Spring提供的用於訪問Http接口的客戶端,提供同步的API;在將來的Spring版本中可能會過時,將逐漸被WebClient替代。文中所使用到的軟件版本:Java 1.8.0_191、SpringBoot 2.2.1.RELEASE。

1、服務端

參見Java調用Http接口(1)--編寫服務端 

2、調用Http接口

2.1、GET請求

    public static void get() {
        try {
            String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=李白";
            RestTemplate template = new RestTemplate();
            //System.out.println(template.getMessageConverters());
            //第二個為StringHttpMessageConverter
            template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            ResponseEntity<String> response = template.getForEntity(requestPath, String.class);
            System.out.println("get返回狀態:" + response.getStatusCode());
            System.out.println("get返回結果:" + response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.2、POST請求(發送鍵值對數據)

    public static void post() {
        String requestPath = "http://localhost:8080/demo/httptest/getUser";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        MultiValueMap<String, String> map = new LinkedMultiValueMap <String, String>();
        map.add("userId", "1000");
        map.add("userName", "李白");
        ResponseEntity<String> response = template.postForEntity(requestPath, map, String.class);
        System.out.println("post返回狀態:" + response.getStatusCode());
        System.out.println("post返回結果:" + response.getBody());
    }

2.3、POST請求(發送JSON數據)

    public static void post2() {
        String requestPath = "http://localhost:8080/demo/httptest/addUser";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        
        String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        HttpEntity<String> entity =  new HttpEntity<String>(param, headers);
        ResponseEntity<String> response = template.postForEntity(requestPath, entity, String.class);
        System.out.println("post json返回狀態:" + response.getStatusCode());
        System.out.println("post json返回結果:" + response.getBody());
    }

2.4、上傳文件

    public static void upload() {
        String requestPath = "http://localhost:8080/demo/httptest/upload";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "file/*");
        HttpEntity<FileSystemResource> entity =  new HttpEntity<FileSystemResource>(new FileSystemResource("d:/a.jpg"), headers);
        
        ResponseEntity<String> response = template.postForEntity(requestPath, entity, String.class);
        System.out.println("upload返回狀態:" + response.getStatusCode());
        System.out.println("upload返回結果:" + response.getBody());
    }

2.5、上傳文件及發送鍵值對數據

    public static void mulit() {
        String requestPath = "http://localhost:8080/demo/httptest/multi";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        MultiValueMap<String, Object> map = new LinkedMultiValueMap <String, Object>();
        map.add("param1", "參數1");
        map.add("param2", "參數2");
        map.add("file", new FileSystemResource("d:/a.jpg"));
        ResponseEntity<String> response = template.postForEntity(requestPath, map, String.class);
        System.out.println("mulit返回狀態:" + response.getStatusCode());
        System.out.println("mulit返回結果:" + response.getBody());
    }

2.6、完整例子

package com.inspur.demo.http.client;

import java.nio.charset.Charset;

import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * 
 * 通過RestTemplate調用Http接口
 *
 */
public class RestTemplateCase {
    /**
     *  GET請求
     */
    public static void get() {
        try {
            String requestPath = "http://localhost:8080/demo/httptest/getUser?userId=1000&userName=李白";
            RestTemplate template = new RestTemplate();
            //System.out.println(template.getMessageConverters());
            //第二個為StringHttpMessageConverter
            template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            ResponseEntity<String> response = template.getForEntity(requestPath, String.class);
            System.out.println("get返回狀態:" + response.getStatusCode());
            System.out.println("get返回結果:" + response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     *  POST請求(發送鍵值對數據)
     */
    public static void post() {
        String requestPath = "http://localhost:8080/demo/httptest/getUser";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        MultiValueMap<String, String> map = new LinkedMultiValueMap <String, String>();
        map.add("userId", "1000");
        map.add("userName", "李白");
        ResponseEntity<String> response = template.postForEntity(requestPath, map, String.class);
        System.out.println("post返回狀態:" + response.getStatusCode());
        System.out.println("post返回結果:" + response.getBody());
    }
    
    /**
     *  POST請求(發送json數據)
     */
    public static void post2() {
        String requestPath = "http://localhost:8080/demo/httptest/addUser";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        
        String param = "{\"userId\": \"1001\",\"userName\":\"杜甫\"}";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        HttpEntity<String> entity =  new HttpEntity<String>(param, headers);
        ResponseEntity<String> response = template.postForEntity(requestPath, entity, String.class);
        System.out.println("post json返回狀態:" + response.getStatusCode());
        System.out.println("post json返回結果:" + response.getBody());
    }
    
    /**
     * 上傳文件
     */
    public static void upload() {
        String requestPath = "http://localhost:8080/demo/httptest/upload";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "file/*");
        HttpEntity<FileSystemResource> entity =  new HttpEntity<FileSystemResource>(new FileSystemResource("d:/a.jpg"), headers);
        
        ResponseEntity<String> response = template.postForEntity(requestPath, entity, String.class);
        System.out.println("upload返回狀態:" + response.getStatusCode());
        System.out.println("upload返回結果:" + response.getBody());
    }
    
    /**
     * 上傳文件及發送鍵值對數據
     */
    public static void mulit() {
        String requestPath = "http://localhost:8080/demo/httptest/multi";
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        MultiValueMap<String, Object> map = new LinkedMultiValueMap <String, Object>();
        map.add("param1", "參數1");
        map.add("param2", "參數2");
        map.add("file", new FileSystemResource("d:/a.jpg"));
        ResponseEntity<String> response = template.postForEntity(requestPath, map, String.class);
        System.out.println("mulit返回狀態:" + response.getStatusCode());
        System.out.println("mulit返回結果:" + response.getBody());
    }
    
    public static void main(String[] args) {
        get();
        post();
        post2();
        upload();
        mulit();
    }
}
View Code

3、調用Https接口

與調用Http接口不一樣的部分主要在設置ssl部分,設置方法是擴展SimpleClientHttpRequestFactory並在prepareConnection方法中進行ssl的設置;ssl的設置與HttpsURLConnection很相似(參見Java調用Http/Https接口(2)--HttpURLConnection/HttpsURLConnection調用Http/Https接口);下面用GET請求來演示ssl的設置,其他調用方式類似。

package com.inspur.demo.http.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import com.inspur.demo.common.util.FileUtil;

/**
 * 通過RestTemplate調用Https接口
 */
public class RestTemplateHttpsCase {
    public static void main(String[] args) {
        try {
            /*
             * 請求有權威證書的地址
             */
            String requestPath = "https://www.baidu.com/";
            RestTemplate template = new RestTemplate();
            template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            ResponseEntity<String> response = template.getForEntity(requestPath, String.class);
            System.out.println("get1返回結果:" + response.getBody());
            
            /*
             * 請求自定義證書的地址
             */
            //獲取信任證書庫
            KeyStore trustStore = getkeyStore("jks", "d:/temp/cacerts", "123456");
            
            //不需要客戶端證書
            requestPath = "https://10.40.x.x:9010/zsywservice";
            template = new RestTemplate(new HttpsClientRequestFactory(trustStore));
            template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            response = template.getForEntity(requestPath, String.class);
            System.out.println("get2返回結果:" + response.getBody());
            
            //需要客戶端證書
            requestPath = "https://10.40.x.x:9016/zsywservice";
            KeyStore keyStore = getkeyStore("pkcs12", "d:/client.p12", "123456");
            template = new RestTemplate(new HttpsClientRequestFactory(keyStore, "123456", trustStore));
            template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8")));
            response = template.getForEntity(requestPath, String.class);
            System.out.println("get3返回結果:" + response.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 獲取證書
     * @return
     */
    private static KeyStore getkeyStore(String type, String filePath, String password) {
        KeyStore keySotre = null;
        FileInputStream in = null;
        try {
            keySotre = KeyStore.getInstance(type);
            in = new FileInputStream(new File(filePath));
            keySotre.load(in, password.toCharArray());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            FileUtil.close(in);
        }
        return keySotre;
    }
    
    /**
     * 擴展SimpleClientHttpRequestFactory以支持Https
     */
    private static class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
        private KeyStore keyStore;
        private String keyStorePassword;
        private KeyStore trustStore;
        
        public HttpsClientRequestFactory(KeyStore keyStore, String keyStorePassword, KeyStore trustStore) {
            this.keyStore = keyStore;
            this.keyStorePassword = keyStorePassword;
            this.trustStore = trustStore;
        }
        
        public HttpsClientRequestFactory(KeyStore trustStore) {
            this.trustStore = trustStore;
        }
        
        @Override
        protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
            try {
                if (!(connection instanceof HttpsURLConnection)) {
                    throw new RuntimeException("An instance of HttpsURLConnection is expected");
                }
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;

                KeyManager[] keyManagers = null;
                TrustManager[] trustManagers = null;
                if (this.keyStore != null) {
                    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
                    keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
                    keyManagers = keyManagerFactory.getKeyManagers();
                }
                if (this.trustStore != null) {
                    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
                    trustManagerFactory.init(trustStore);
                    trustManagers = trustManagerFactory.getTrustManagers();
                } else {
                    trustManagers = new TrustManager[] { new DefaultTrustManager()};
                }
                
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(keyManagers, trustManagers, null);
                httpsConnection.setSSLSocketFactory(sslContext.getSocketFactory());
                //驗證URL的主機名和服務器的標識主機名是否匹配
                httpsConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String s, SSLSession sslSession) {
                        //if ("xxx".equals(hostname)) {
                        //    return true;
                        //} else {
                        //    return false;
                        //}
                        return true;
                    }
                });

                super.prepareConnection(httpsConnection, httpMethod);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    private static final class DefaultTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}

4、AsyncRestTemplate

該模板已過時,建議使用WebClient替代。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM