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"))); ResponseEntityresponse = 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"))); MultiValueMapmap = new LinkedMultiValueMap (); map.add("userId", "1000"); map.add("userName", "李白"); ResponseEntity 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"); HttpEntityentity = new HttpEntity (param, headers); ResponseEntity 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/*"); HttpEntityentity = new HttpEntity (new FileSystemResource("d:/a.jpg"), headers); ResponseEntity 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"))); MultiValueMapmap = new LinkedMultiValueMap (); map.add("param1", "参数1"); map.add("param2", "参数2"); map.add("file", new FileSystemResource("d:/a.jpg")); ResponseEntity 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"))); ResponseEntityresponse = 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 map = new LinkedMultiValueMap (); map.add("userId", "1000"); map.add("userName", "李白"); ResponseEntity 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 entity = new HttpEntity (param, headers); ResponseEntity 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 entity = new HttpEntity (new FileSystemResource("d:/a.jpg"), headers); ResponseEntity 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 map = new LinkedMultiValueMap (); map.add("param1", "参数1"); map.add("param2", "参数2"); map.add("file", new FileSystemResource("d:/a.jpg")); ResponseEntity 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(); } }
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.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 { /** * GET请求 */ public static void get() { try { String requestPath = "https://x.x.x.x:9010/x"; //不需要证书 RestTemplate template = new RestTemplate(new HttpsClientRequestFactory()); template.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8"))); ResponseEntityresponse = template.getForEntity(requestPath, String.class); System.out.println("get(不需要证书)返回结果:" + response.getBody()); String requestPath2 = "https://x.x.x.x:9016/x"; //需要证书 RestTemplate template2 = new RestTemplate(new HttpsClientRequestFactory(getkeyStore("d:/client.p12", "123"), "123")); template2.getMessageConverters().set(1, new StringHttpMessageConverter(Charset.forName("UTF-8"))); ResponseEntity response2 = template2.getForEntity(requestPath2, String.class); System.out.println("get(需要证书)返回结果:" + response2.getBody()); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { get(); } /** * 获取证书 * @return */ private static KeyStore getkeyStore(String filePath, String password) { KeyStore keySotre = null; FileInputStream in = null; try { keySotre = KeyStore.getInstance("PKCS12"); 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 password; public HttpsClientRequestFactory() { } public HttpsClientRequestFactory(KeyStore keyStore, String password) { this.keyStore = keyStore; this.password = password; } @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; if (this.keyStore != null) { KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keyStore, password.toCharArray()); keyManagers = keyManagerFactory.getKeyManagers(); } SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, new TrustManager[]{ new DefaultTrustManager()}, null); httpsConnection.setSSLSocketFactory(sslContext.getSocketFactory()); httpsConnection.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { 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替代。