RestTemplate
由于我的项目需要做一个定位的功能,打算引用百度的API来进行地址的查询。因为要调用那个API需要百度开发者的密钥key,我不打算直接让前端使用key直接在前端进行调用,因为我认为这样会导致我的密钥的泄漏。所以打算把调用API这一步封装在自己的Service层里。
常用的方式是HttpClient,但我觉得有点麻烦,而且代码篇幅有点长,比较零散。就想着万能的spring有没有什么好的解决方案。一看还真有,spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。
首先看名字就能感觉很眼熟,跟spring的其他模版类JdbcTemplate,RedisTemplate等差不多,都是为复杂的process提供简化易懂的方法。
配置
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
这是最简单的配置方式,直接返回就好,如果要根据自己的需要来配置的话,引入一个RestTemplateBuilder类的参数,用builder来创建一个模版类。
GET请求
restTemplate提供了两个get请求的方法,一个是getForEntity,一个是getForObject。
getForEntity
getForEntity 方法的返回值是一个ResponseEntity<T>
。
ResponseEntity<T>
是 Spring 对 HTTP 请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。使用ResponseEntity作为controller的返回值,我们可以方便地处理响应的header,状态码以及body。而通常使用的@ResponseBody注解,只能处理body部分。这也是为什么通常在下载场景中会使用ResponseEntity,因为下载需要设置header里的content-type以及特殊的status(比如206)。
ResponseEntity其实可以看做是把HttpServletResponse封装了,但是功能比HttpServletResponse多,我是推荐在spring中使用的。
- 第一个参数是请求的URL,可以使用拼接字符串的方式设置请求参数。
- 第二个参数是期望得到响应的body的类型,一般是String.class就行,也可以填入实体类让spring来自动装配。
请求参数的设置方式有三种:
-
直接拼接字符串URL。
-
设置占位符
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, "张三");
-
通过map传入
Map<String, String> map = new HashMap<>(); map.put("name", "李四"); ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map);
getForObject
与上面那个方法差别不大,只是返回的对象是响应的body。实际上是对Entity的一个封装。
POST请求
postForEntity
与getForEntity的差别主要就是参数位置的差异
- 方法的第一参数表示要调用的服务的地址
- 方法的第二个参数表示上传的参数
- 方法的第三个参数表示返回的消息体的数据类型
public User getUser() {
User user = new User();
User.setName("wzl");
ResponseEntity<User> responseEntity = restTemplate.postForEntity("xxxxxxxxxxxxxxxxxx", user, com.wzl.market.pojo.User.class);
return responseEntity.getBody();
}
postForObject
注意参数的位置之外和getForObject没什么太大差别。
PUT请求
既然是名字里带了REST,那肯定是还支持RESTful风格的请求的。
因为是put操作,所以restTemplate里面的put请求方法是没有返回值的。别的和post请求一样。
DELETE请求
和get也没什么差别,就是不用填返回响应体的类型参数了。
restTemplate.delete("xxxxxxxxxxxx/{1}", 100);