RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,Spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接,我们只需要传入url及返回值类型即可。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。当然也可以通过setRequestFactory属性切换到不同的HTTP源,如Apache HttpComponents、Netty和OkHttp。
GET请求
首先在provider类中定义一个hello2的接口
@GetMapping("/hello2")
public String hello2(String name){
return "hello"+name;
}
之后用consumer去访问它,这个接口是一个GET请求,所以访问方式也需要调用
RestTemplate中的GET请求。
在RestTemplate,关于GET请求有两大类方法:
- getForObject:返回一个对象,该对象客户端返回的具体值
- getForEntity:返回ResponseEntity,在ResponseEntity中除了服务端返回的具体数据外还保留了http响应头的数据。
@GetMapping("/hello3")
public void hello3(){
String s1 = restTemplate.getForObject("http://provider/hello2?name={1}", String.class,"spring cloud");
System.out.println(s1);
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://provider/hello2", String.class,"spring cloud");
String body = responseEntity.getBody();
System.out.println("body:"+body);
HttpStatus statusCode = responseEntity.getStatusCode();
System.out.println("HttpStatus:"+statusCode);
int statusCodeValue = responseEntity.getStatusCodeValue();
System.out.println("statusCodeValue:"+statusCodeValue);
HttpHeaders headers = responseEntity.getHeaders();
Set<String> keySet = headers.keySet();
System.out.println("--------header-------");
for (String s : keySet) {
System.out.println(s+":"+headers.get(s));
}
}
打印所有的返回值信息,可以看到getForObject值返回了客户端返回的具体值,而getForEntity除了服务端返回的具体数据外还保留了http响应头的数据。
访问http://localhost:1114/hello3后,可以看到如下信息:
POST请求
首先创建一个普通的Maven项目作为一个公共模块,在commons中添加User对象。之后在pom.xml中添加依赖,使这个模块可以被provider和consumer共同调用。
<dependency>
<groupId>com.example</groupId>
<artifactId>commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在provider中提供两个POST接口,分别以keyValue和Json的方式传递参数:
//keyValue传参
@PostMapping("/user1")
public User addUser1(User user){
return user;
}
//Json传参,这里要在参数前加@RequestBody注解
@PostMapping("/user2")
public User addUser2(@RequestBody User user){
return user;
}
定义完成后,在consumer中调用两个post接口
@GetMapping("/hello4")
public void hello4(){
//keyValue形式传参
MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
map.add("username","zby");
map.add("password","123");
map.add("id",99);
User user = restTemplate.postForObject("http://provider/user1", map, User.class);
System.out.println(user);
//Json形式传参
user.setId(98);
user = restTemplate.postForObject("http://provider/user2", user, User.class);
System.out.println(user);
}
POST参数是keyValue形式还是Json形式主要看第二个参数,如果第二个参数是
MultiValueMap形式,则参数以keyValue形式传递;若第二个参数是一个普通对象,则参数以Json形式传递
相对于GET请求,POST请求多了一个postForLocation()方法。当执行完一个POST请求后马上要进行重定向,例如:注册是一个常见POST请求,注册完成后要马上重定向到登录页面去登录。对于这种场景,就需要使用postForLocation()
在provider中提供一个注册接口,注册成功后返回用户名
@Controller
public class RegisterController {
@PostMapping
public String register(User user){
return "redirect:http://provider/loginPage?username="+user.getUsername();
}
@GetMapping("/loginPage")
@ResponseBody
public String loginPage(String username){
return "loginPage:"+username;
}
}
这里post接口的响应码一定是302,否则postForLocation无效
注意:重定向地址一定要写成绝对路径,写成相对路径在consumer中调用时可能会出错
postForLocation()返回值是一个URI这个URI即是重定向地址。拿到URI后即可访问新的地址。
@GetMapping("/hello5")
public void hello5(){
MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
map.add("username","zby");
map.add("password","123");
map.add("id",99);
URI uri = restTemplate.postForLocation("http://provider/register", map);
String s = restTemplate.getForObject(uri, String.class);
System.out.println(s);
}
PUT请求
在provider中提供PUT接口,PUT请求与POST请求相似同样也有keyValue传值和Json传值两种形式
@PostMapping("/user1")
public void updateUser1(User user){
System.out.println(user);
}
@PostMapping("/user2")
public void updateUser2(@RequestBody User user){
System.out.println(user);
}
在consumer中调用接口,写法也基本与POST一致
@GetMapping("/hello6")
public void hello6(){
//keyValue
MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
map.add("username","zby");
map.add("password","123");
map.add("id",99);
restTemplate.put("http://provider/user1",map);
//Json
User user = new User();
user.setId(98);
user.setUsername("zheng");
user.setPassword("111");
restTemplate.put("http://provider/user2",user);
}
DELETE请求
在provider中提供DELETE接口,DELETE请求同样也有两种方式传递参数,keyValue形式或PathVariable形式(参数放在路径中)
@DeleteMapping("/user1")
public void deleteUser1(Integer id){
System.out.println(id);
}
@DeleteMapping("/user2/{id}")
public void deleteUser2(@PathVariable Integer id){
System.out.println(id);
}
在consumer中调用接口
@GetMapping("/hello7")
public void hello7(){
restTemplate.delete("http://provider/user1?id={1}",99);
restTemplate.delete("http://provider/user2/{1}",99);
}
delete中参数传递也支持map,类似GET请求。
网友评论