一、认识RestTemplate
RestTemplate
是
Spring
提供的用于访问
RESTful
服务的客户端,
RestTemplate
提供了多种便捷访问远程
Http
服务 的方法,
能够大大提高客户端的编写效率。
RestTemplate
默认依赖
JDK
提供
http
连接的能力 (HttpURLConnection
),也可以通过替换为例如
Apache HttpComponents
、
Netty
或
OkHttp
等其它
HTTP
客户端,目前OkHttp
的性能最优越。
官网:
https://square.github.io/okhttp/
,
github
:
https://github.com/square/okhttp
二、集成RestTemplate
1、添加依赖
<!‐‐ okhttp3依赖 ‐‐>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.1</version>
</dependency>
2、RestTemplate初始化
package com.ruoyi.framework.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate(new OkHttp3ClientHttpRequestFactory());
//得到消息转换器
List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
//指定StringHttpMessageConverter消息转换器的字符集为utf-8中文编码
messageConverters.set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
//设置支持的媒体类型 json/text
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_HTML));
// 添加MappingJackson2HttpMessageConverter转换器
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
return restTemplate;
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(600_000);//单位为ms
factory.setConnectTimeout(60_000);//单位为ms
return factory;
}
}
注意:当RestTemplate默认使用String存储body内容时默认使用ISO_8859_1字符集。必须配置StringHttpMessageConverter 消息转换器,使用utf-8字符集,要不然中文乱码。
三、测试
一、使用RestTemplate获取百度的网页内容和短信测试
package com.***.merchant;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* @author xiyuan
* @version 1.0
**/
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class RestTemplateTest {
@Autowired
RestTemplate restTemplate;
//测试使用restTemplate作为http的客户端向http服务端发起请求
@Test
public void gethtml(){
String url = "http://www.baidu.com/";
//向url发送http请求,得到响应结果
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
String body = forEntity.getBody();
System.out.println(body);
}
//向验证码服务发送请求,获取验证码
//http://localhost:56085/sailing/generate?effectiveTime=600&name=sms
@Test
public void getSmsCode(){
String url = "http://localhost:56085/sailing/generate?effectiveTime=600&name=sms";
//请求体
Map<String,Object> body = new HashMap<>();
body.put("mobile","133456");
//请求头
HttpHeaders httpHeaders =new HttpHeaders();
//指定Content-Type: application/json
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
//请求信息,传入body,header
HttpEntity httpEntity = new HttpEntity(body,httpHeaders);
//向url请求
ResponseEntity<Map> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Map.class);
log.info("请求验证码服务,得到响应:{}", JSON.toJSONString(exchange));
Map bodyMap = exchange.getBody();
System.out.println(bodyMap);
Map result = (Map) bodyMap.get("result");
String key = (String) result.get("key");
System.out.println(key);
}
}
二、获取企业微信 AccessToken
具体示例见:企业微信授权获取access_token
@Component
@Slf4j
public class QiYeWeChatUtil {
/**
* 缓存企业微信accessToken
*/
public static final String QY_WX_TOKEN_kEY = "qy_wx_token:";
@Autowired
private QyWxConfig qyWxConfig;
@Resource
private RestService restService;
@Autowired
private RedisCache redisCache;
/**
* 获取企业微信 AccessToken
*
* @return
*/
public String getAccessToken() {
if (!redisCache.hasKey(QY_WX_TOKEN_kEY)) {
//请求头
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON);
//请求信息,传入header
HttpEntity<Map<String, String>> formEntity = new HttpEntity<>(header);
StringBuilder urlBuilder = new StringBuilder(企业微信tUrl());
urlBuilder.append("?").append("corpid=").append(企业微信Corpid());
urlBuilder.append("&").append("corpsecret=").append(企业微信tCorpsecret());
try {
ResponseEntity<Map> entity = restService.getForEntity(urlBuilder.toString(), formEntity, Map.class);
log.info("请求企业微信,得到响应:{}", entity);
Map body = entity.getBody();
String accessToken = (String) body.get("access_token");
Integer expires_in = (Integer) body.get("expires_in");
redisCache.setCacheObject(QY_WX_TOKEN_kEY,accessToken, 7200, TimeUnit.SECONDS);
log.info("请求企业微信,获取accessToken成功有效时间为:{}", expires_in + "分钟");
return accessToken;
} catch (Exception e) {
log.error("获取token失败:{}", e);
}
}
log.info("从Redis缓存中获取的accessToken");
return redisCache.getCacheObject(QY_WX_TOKEN_kEY);
}
}