介绍
我们项目中或多或少会调用外部的接口,请求格式多为XML或者JSON传输,这里我们使用Spring提供的RestTemplate模板类,它简化了与HTTP服务器的通信,并强制执行RESTful原则,对请求体跟返回结果的解析提供了封装,我们做一些简单的配置即可开箱即用。
RestTemplate配置
@Slf4j
@Component
public class RestTemplateConfig {
/**
* 通过ClientHttpRequestFactory生成RestTemplate还可以扩展配置RestTemplate
* @param factory
* @return
*/
@Bean
@ConditionalOnMissingBean({RestTemplate.class})
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
log.info("---------【RestTemplate加载】------------");
RestTemplate restTemplate = new RestTemplate(factory);
// Converter处理
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
// 默认StringHttpMessageConverter的编码集是ISO-8859-1 , 会导致乱码
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setDefaultCharset(Charset.forName("UTF-8"));
continue;
}
if (converter instanceof MappingJackson2HttpMessageConverter) {
List<MediaType> mediaTypeList = new ArrayList<>();
//增加text的解析
mediaTypeList.addAll( Arrays.asList(MediaType.TEXT_PLAIN,MediaType.TEXT_HTML) );
mediaTypeList.addAll( converter.getSupportedMediaTypes() );
((MappingJackson2HttpMessageConverter) converter).setSupportedMediaTypes( mediaTypeList );
continue;
}
}
return restTemplate;
}
/**
* 生成一个ClientHttpRequestFactory并配置相应参数
*
* @return
*/
@Bean
@ConditionalOnMissingBean({ClientHttpRequestFactory.class})
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
log.info("---------【ClientHttpRequestFactory加载】------------");
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// 读取超时时间 单位为ms
factory.setReadTimeout(15000);
// 连接超时时间w 单位为ms
factory.setConnectTimeout(15000);
return factory;
}
}
注意事项:RestTemplate配置的时候内部的转换器HttpMessageConverter不可以打乱顺序,如先删除再自定义添加, 这样会在后续的调用中出现各种奇怪的错误,如果修改我们保留他自己的顺序我们在这个基础上修改即可,如上我们增加了text请求格式的解析。
自定义封装客户端
@Slf4j
@Service
public class RestTemplateClient {
/**
* 注入对象
*/
@Autowired
private RestTemplate restTemplate;
/**
* 发送post请求
* @param url:请求地址
* @param paramXml:请求参数
* @return
*/
public ResponseEntity doPostForXML_UTF8(String url, String paramXml) {
//不进行大小写转换,默认转换json时 会将首字母改成大写
TypeUtils.compatibleWithJavaBean = true;
HttpHeaders headers = new HttpHeaders();
headers.setContentType( MediaType.APPLICATION_XML );
HttpEntity<String> httpEntity = new HttpEntity( paramXml , headers);
ResponseEntity responseEntity = null;
try {
log.info("开始调用接口,接口地址:{},请求参数:{}", url, paramXml );
responseEntity = restTemplate.postForEntity(url, httpEntity, null);
restTemplate.getMessageConverters();
restTemplate.getMessageConverters();
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (responseEntity == null) {
return null;
}
log.info("responseEntity = {}", JSON.toJSONString(responseEntity));
return responseEntity;
}
/**
* 发送post请求
* @param url:请求地址
* @param param:请求参数
* @param responseType:返回类型
* @return
*/
public <T> T doPostForJSON_UTF8(String url, Object param, Class<T> responseType) {
//不进行大小写转换,默认转换json时 会将首字母改成大写
TypeUtils.compatibleWithJavaBean = true;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<Object> httpEntity = new HttpEntity(param, headers);
ResponseEntity<T> responseEntity = null;
try {
log.info("开始调用接口,接口地址:{},请求参数:{}", url);
responseEntity = restTemplate.postForEntity(url, httpEntity, responseType);
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (responseEntity == null) {
return null;
}
//log.info("responseEntity = {}", JSON.toJSONString(responseEntity));
return responseEntity.getBody();
}
/**
* 发送post请求
*
* @param url:请求地址
* @param responseType:返回类型
* @return
*/
public <T> T doPostForUrlencoded(String url,Class<T> responseType) {
//不进行大小写转换,默认转换json时 会将首字母改成大写
TypeUtils.compatibleWithJavaBean = true;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<String> httpEntity = new HttpEntity(headers);
ResponseEntity<T> responseEntity = null;
try {
log.info("开始调用接口,接口地址:{}", url);
responseEntity = restTemplate.postForEntity(url, httpEntity, responseType);
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (responseEntity == null) {
return null;
}
//log.info("responseEntity = {}", JSON.toJSONString(responseEntity));
return responseEntity.getBody();
}
/**
* 发送post请求
*
* @param url:请求地址
* @param multiValueMap:请求参数
* @param responseType:返回类型
* @return
*/
public <T> T doPostHeaderForJSON_UTF8(String url, String header, MultiValueMap<String, Object> multiValueMap, Class<T> responseType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("Authorization", header);
String body = null;
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(multiValueMap, headers);
ResponseEntity<T> responseEntity = null;
try {
log.info("开始调用接口,接口地址:{},请求参数:{}", url, body);
responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, responseType);
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (responseEntity == null) {
return null;
}
return responseEntity.getBody();
}
/**
* 发送 put请求
*
* @param url:请求地址
* @param responseType:返回类型
* @return
*/
public ResponseEntity doPutAuthForJSON_UTF8(String url, Object requestBody , Class responseType) {
HttpEntity<String> httpEntity = new HttpEntity(requestBody );
ResponseEntity<String> responseEntity = null;
try {
log.info("开始调用接口,接口地址:{},", url);
responseEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, responseType);
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (responseEntity == null) {
return null;
}
return responseEntity;
}
/**
* 发送 put请求
* @param url:请求地址
* @return
*/
public HttpHeaders doHeadForJSON_UTF8(String url) {
HttpHeaders httpHeaders = null;
try {
log.info("开始调用接口,接口地址:{},", url);
httpHeaders = restTemplate.headForHeaders(url);
} catch (RestClientException e) {
log.error("接口调用出错:{}", e);
}
if (httpHeaders == null) {
return null;
}
return httpHeaders;
}
/**
* 发送 put请求
*
* @param url:请求地址
* @param responseType:返回类型
* @return
*/
public <T> T doGetAuthForJSON_UTF8(String url, String headAuth, Class<T> responseType) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
if( headAuth != null && !Objects.equals(headAuth , "")){
headers.add("Authorization", headAuth);
}
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<T> responseEntity = null;
try {
log.info("开始调用接口,接口地址:{},请求headers:{} ", url);
responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, responseType);
} catch (RestClientException e) {
log.warn("接口调用出错:{}", e.getMessage());
}
if (responseEntity == null) {
return null;
}
return responseEntity.getBody();
}
public <T> T doGetAuthForJSON_UTF8(String url, Class<T> responseType) {
return doGetAuthForJSON_UTF8(url , null , responseType);
}
/**
* 发送post请求
*
* @param url
* @param jsonObject:请求参数
* @return
*/
public String doPostForJSON_UTF8(String url, Object jsonObject) {
return doPostForJSON_UTF8(url, jsonObject, String.class);
}
/**
* 发送post请求
*
* @param url
* @return
*/
public String doPostForJSON_UTF8(String url) {
return doPostForJSON_UTF8(url, null, String.class);
}
/**
* 发送post请求
*
* @param url
* @param responseType:返回类型
* @return
*/
public <T> T doPostForJSON_UTF8(String url, Class<T> responseType) {
return doPostForJSON_UTF8(url, null, responseType);
}
}
总结
RestTemplate经过简单的封装,后续的使用就特别的方便,整个项目中我们可以用同一套HTTP请求方法就行了, 这样也防止一个项目只使用过的的HTTP工具类,导致依赖过多,代码冗余,维护工作了增大。
本文暂时没有评论,来添加一个吧(●'◡'●)