RestTemplate详解
服务端访问HTTP服务随处可见!传统情况下我们都会使用Apache的HttpClient,不过Apache的封装的API非常复杂,还得自己做二次封装和管理资源的回收,因此在项目上非常推荐使用Spring提供的模板类RestTemplate发HTTP请求,RestTemplate封装了更加简单易用的API,能很大程度提升开发者的开发效率。
1、RestTemplate
1.1、引子
RestTemplate是一个同步阻塞式的web客户端工具类,封装了各种简单易用API。底层默认初始化的执行引擎是JDK的java.net.HttpURLConnection ,并且我们还可以灵活替换底层的执行引擎,例如可以替换为Netty、OkHttp 或Apache HttpComponents 都是支持的。
例如创建RestTemplate 对象时,只需传入一个实现了ClientHttpRequestFactory 接口的接口实现类即可。
@Configuration
public class RestTemplateConfiguration {
@Bean(name = "restTemplate")
public RestTemplate restTemplate() {
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
return new RestTemplate(factory);
}
}
但是要引入相关依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
1.2、发送GET请求
发送GET 请求RestTemplate封装了两个核心API:
1、getForObject() 返回值是一个Java 对象(实际上是HTTP 协议的响应体,可按指定的泛型进行转换)
@SpringBootTest
public class RestTemplateTest {
private final org.apache.logging.log4j.Logger log = Logger.getLogger(RestTemplateTest.class);
@Autowired
private RestTemplate restTemplate;
private final String baseUrl = "https://api.github.com/users";
@Test
public void test1() {
String resp = restTemplate.getForObject(baseUrl, String.class);
JSONArray userList = JSON.parseArray(resp);
if (userList == null || userList.size() == 0) {
log.error("查询为空");
return;
}
for (int i = 0; i < userList.size(); i++) {
JSONObject item = (JSONObject) userList.get(i);
log.info("loginName=" + item.get("login"));
log.info("avatarUrl=" + item.get("avatar_url"));
}
}
@Test
public void test2() {
Map<String, Object> param = new HashMap<>();
param.put("login", "mojombo");
param.put("page", 3);
String resp = restTemplate.getForObject(baseUrl + "/{login}/repos?page={page}", String.class, param);
log.info(resp);
}
}
2、getForEntity() 返回值是ResponseEntity ,ResponseEntity 是对HTTP 响应Java 层面的封装,包括响应体、HTTP 状态码、contentType 、Header 等信息。
@Test
public void test3() {
Map<String, Object> param = new HashMap<>();
param.put("login", "mojombo");
param.put("page", 3);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(baseUrl + "/{login}/repos?page={page}", String.class, param);
log.info(responseEntity.getBody());
}
@Test
public void test4() {
Map<String, Object> param = new HashMap<>();
param.put("login", "mojombo");
String resp = restTemplate.getForObject(baseUrl + "/{login}", String.class, param);
JSONObject response = JSON.parseObject(resp);
String avatarUrl = (String) response.get("avatar_url");
ResponseEntity<org.springframework.core.io.Resource> responseEntity = restTemplate.getForEntity(avatarUrl,
org.springframework.core.io.Resource.class);
InputStream inputStream = null;
OutputStream outputStream = null;
File file = null;
try {
inputStream = Objects.requireNonNull(responseEntity.getBody()).getInputStream();
file = new File("src/main/resources/static/mojombo.png");
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
log.error(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error(e);
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
}
HTTP 状态码扩展:
分类 | 描述 |
---|
2xx | 表示请求成功,服务端已成功接收并处理请求 | 3xx | 重定向,需要进一步操作以完成请求 | 4xx | 客户端请求错误请求包含语法错误或无法完成请求 | 5xx | 服务端错误,服务端在处理请求的过程中发生了错误 |
1.3、发送POST请求
|