使用 Spring 的 RestTemplate 发送请求
RestTemplate是什么
RestTemple是Spring提供的用于访问Http请求的客户端,RestTemple提供了多种简洁的远程访问服务的方法,省去了很多无用的代码。
为什么要用RestTemplate
相信大家之前都用过apache的HTTPClient类,逻辑繁琐,代码复杂,还要自己编写使用类HttpClientUtil,封装对应的post,get,delete等方法。
RestTemplate的行为可以通过callback回调方法和配置HttpMessageConverter 来定制,用来把对象封装到HTTP请求体,将响应信息放到一个对象中。RestTemplate提供更高等级的符合HTTP的六种主要方法,可以很简单的调用RESTful服务。
具体使用
GET 无参请求
// 设置请求地址
String sendUrl = "http://192.168.12.11/user/allDAta";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置访问的entity
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> result = null;
JSONObject data = null;
try {
// 发送一个get请求
result = restTemplate.exchange(sendUrl, HttpMethod.GET, entity, String.class);
data = JSONObject.parseObject(result.getBody()).getJSONObject("data");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(data);
GET 有参请求
// 设置请求地址
String sendUrl = "http://192.168.12.11/user/allDAta";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置访问参数
HashMap<String, Object> params = new HashMap<>(0);
params.put("page", 1);
params.put("size", 10);
// 设置访问的entity
HttpEntity entity = new HttpEntity(params, headers);
ResponseEntity<String> result = null;
JSONObject data = null;
try {
result = restTemplate.exchange(sendUrl, HttpMethod.GET, entity, String.class);
data = JSONObject.parseObject(result.getBody()).getJSONObject("data");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(data);
POST 参数请求
String sendUrl = "http://192.168.12.11/user/insert";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", token);
// 设置请求数据
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(0);
params.add("username", entity.getUsername());
params.add("password",entity.getPassword());
HttpEntity httpEntity = new HttpEntity(params, headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
// 发送一个post请求
result = restTemplate.exchange(sendUrl, HttpMethod.POST, httpEntity, String.class);
flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(flag);
POST 实体请求
String sendUrl = "http://192.168.12.11/user/insert";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置请求数据
AddUserVO addUserVO = new AddUserVO();
addUserVO.setUserId(entity.getId());
addUserVO.setUsername(entity.getUsername());
addUserVO.setRealname(entity.getName());
addUserVO.setPassword(entity.getPassword());
addUserVO.setPhone(entity.getTel());
HttpEntity httpEntity = new HttpEntity(JSON.toJSON(addUserVO), headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
// 发送一个post请求
if (StrUtil.isNotBlank(entity.getId())) {
result = restTemplate.exchange(sendUrl, HttpMethod.PUT, httpEntity, String.class);
flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
} else {
result = restTemplate.exchange(sendUrl, HttpMethod.POST, httpEntity, String.class);
flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(flag);
PATH 参数请求
String sendUrl = "http://192.168.12.11/user/delete/{id}";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
// {id} 是占位符,请求最后参数对应 占位id
result = restTemplate.exchange(sendUrl, HttpMethod.DELETE, entity, String.class, id);
flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(flag);
请求之后,拿到的结果是一个json类型,我们还需要通过fastjson,Jackson等来处理我们的json字符串,获取到我们想要的数据。
封装工具类
package com.zl.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Component
public class SendHttpUtil {
@Resource
private RestTemplate restTemplate;
/**
* GET 无参请求
*/
public ResponseEntity<String> getRequestNoParams(String httpUrl, Map<String, String> headerParams) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(headers);
ResponseEntity<String> data = null;
try {
data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class);
// 获取 JSONObject.parseObject(data.getBody());
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* GET 有参请求
*/
public ResponseEntity<String> getRequestParams(String httpUrl, Map<String, String> headerParams, HashMap<String, Object> requestParams) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(requestParams, headers);
ResponseEntity<String> data = null;
try {
data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* POST 参数请求
*/
public ResponseEntity<String> postRequestParams(String httpUrl, Map<String, String> headerParams, MultiValueMap<String, Object> requestParams) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(requestParams, headers);
ResponseEntity<String> data = null;
try {
data = restTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* POST 实体请求
*/
public ResponseEntity<String> postRequestEntity(String httpUrl, Map<String, String> headerParams, Object entity) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(JSON.toJSON(entity), headers);
ResponseEntity<String> data = null;
try {
data = restTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
/**
* PATH 参数请求
*/
public ResponseEntity<String> pathRequestParams(String httpUrl, Map<String, String> headerParams, Object requestParams) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(headers);
ResponseEntity<String> data = null;
try {
data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class, requestParams);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
private void setHeaderParams(HttpHeaders headers, Map<String, String> headerParams) {
if (headerParams != null) {
Set<String> headerKeys = headerParams.keySet();
headerKeys.stream().forEach(a -> {
headers.set(a, headerParams.get(a));
});
}
}
}
解决中文乱码
@Bean
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
RestTemplate发起HTTPS请求
因为发起HTTPS请求时需要验证服务端SSL证书,所以在此有两种解决办法,一是
导入证书
,二是忽略证书的校验
。
这里使用的是忽略证书的校验:
缺少SSLContextBuilder导包:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version> <!-- 请使用最新的稳定版本 -->
</dependency>
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@Bean(name = "restHttpsTemplate")
public RestTemplate getRestHttpsTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
// 信任任何链接,忽略对证书的校验
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
return true;
}
}).build();
// 指定使用的TLS协议版本
// SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,
// new String[]{"TLSv1"},
// null,
// NoopHostnameVerifier.INSTANCE);
// NoopHostnameVerifier.INSTANCE 解决No subject alternative names matching IP address xxx.xxx.xxx.xxx found问题
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
封装
@Resource(name = "restHttpsTemplate")
private RestTemplate restHttpsTemplate;
/**
* HTTPS POST 实体请求
*/
public ResponseEntity<String> postHttpsRequestEntity(String httpUrl, Map<String, String> headerParams, Object entity) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
setHeaderParams(headers, headerParams);
HttpEntity httpEntity = new HttpEntity(JSON.toJSON(entity), headers);
ResponseEntity<String> data = null;
try {
data = restHttpsTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
RestTemplate实例和协议不一样,其余的都一样;类比POST即可,这里就不再给出示例了。