RestTemplate 简介
RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。接下来我们就来看看这些操作方法的使用。
用法实战
在开始下面的案例之前,我们需要先创建一个工程,命名为 RestTemplate 。和上篇文章的项目结构一样,在 RestTemplate 中,我们也分别创建子项目 eureka 、provider 以及 consumer ,将 provider 和 consumer 分别注册到 eureka 上面去。这个具体的步骤大家可以参考上篇文章,本文我就不赘述了,这是我们的准备工作。
GET 请求
做好了准备工作,先来看使用 RestTemplate 发送 GET 请求。在 RestTemplate 中,和 GET 请求相关的方法有如下几个:
这里的方法一共有两类,getForEntity 和 getForObject,每一类有三个重载方法,下面我们分别予以介绍。
getForEntity
既然 RestTemplate 发送的是 HTTP 请求,那么在响应的数据中必然也有响应头,如果开发者需要获取响应头的话,那么就需要使用 getForEntity 来发送 HTTP 请求,此时返回的对象是一个 ResponseEntity 的实例。这个实例中包含了响应数据以及响应头。例如,在 provider 中提供一个 HelloController 接口,HelloController 接口中定义一个 sayHello 的方法,如下:
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello(String name) {
return “hello " + name + " !”;
}
}
在 consumer 中定义一个 UseHelloController 的类,再定义一个 /hello 接口,在接口中调用 provider 提供的服务,如下:
@RestController
public class UseHelloController {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
@GetMapping("/hello")
public String hello(String name) {
List<ServiceInstance> list = discoveryClient.getInstances("provider");
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = "http://" + host + ":" + port + "/hello?name={1}";
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, name);
StringBuffer sb = new StringBuffer();
HttpStatus statusCode = responseEntity.getStatusCode();
String body = responseEntity.getBody();
sb.append("statusCode:")
.append(statusCode)
.append("</br>")
.append("body:")
.append(body)
.append("</br>");
HttpHeaders headers = responseEntity.getHeaders();
Set<String> keySet = headers.keySet();
for (String s : keySet) {
sb.append(s)
.append(":")
.append(headers.get(s))
.append("</br>");
}
return sb.toString();
}
}
关于 DiscoveryClient 那一段本文先不做讨论,主要来看 getForEntity 方法。第一个参数是 url ,url 中有一个占位符 {1} ,如果有多个占位符分别用 {2} 、 {3} … 去表示,第二个参数是接口返回的数据类型,最后是一个可变长度的参数,用来给占位符填值。在返回的 ResponseEntity 中,可以获取响应头中的信息,其中 getStatusCode 方法用来获取响应状态码, getBody 方法用来获取响应数据, getHeaders 方法用来获取响应头,在浏览器中访问该接口,结果如下:
当然,这里参数的传递除了这一种方式之外,还有另外两种方式,也就是 getForEntity 方法的另外两个重载方法。
第一个是占位符不使用数字,而是使用参数的 key,同时将参数放入到一个 map 中。map 中的 key 和占位符的 key 相对应,map 中的 value 就是参数的具体值,例如还是上面的请求,利用 map 来传递参数,请求方式如下:
Map<String, Object> map = new HashMap<>();
String url = “http://” + host + “:” + port + “/hello?name={name}”;
map.put(“name”, name);
ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class, map);
这种方式传参可能看起来更直观一些。
第二个是使用 Uri 对象,使用 Uri 对象时,参数可以直接拼接在地址中,例如下面这样:
String url = “http://” + host + “:” + port + “/hello?name=”+ URLEncoder.encode(name,“UTF-8”);
URI uri = URI.create(url);
ResponseEntity responseEntity = restTemplate.getForEntity(uri, String.class);
但需要注意的是,这种传参方式,参数如果是中文的话,需要对参数进行编码,使用 URLEncoder.encode 方法来实现。
getForObject
getForObject 方法和 getForEntity 方法类似,getForObject 方法也有三个重载的方法,参数和 getForEntity 一样,因此这里我就不重复介绍参数了,这里主要说下 getForObject 和 getForEntity 的差异,这两个的差异主要体现在返回值的差异上, getForObject 的返回值就是服务提供者返回的数据,使用 getForObject 无法获取到响应头。例如,还是上面的请求,利用 getForObject 来发送 HTTP 请求,结果如下:
String url = “http://” + host + “:” + port + “/hello?name=” + URLEncoder.encode(name, “UTF-8”);
URI uri = URI.create(url);
String s = restTemplate.getForObject(uri, String.class);
注意,这里返回的 s 就是 provider 的返回值,如果开发者只关心 provider 的返回值,并不关系 HTTP 请求的响应头,那么可以使用该方法。
POST 请求
和 GET 请求相比,RestTemplate 中的 POST 请求多了一个类型的方法,如下:
可以看到,post 请求的方法类型除了 postForEntity 和 postForObject 之外,还有一个 postForLocation。这里的方法类型虽然有三种,但是这三种方法重载的参数基本是一样的,因此这里我还是以 postForEntity 方法为例,来剖析三个重载方法的用法,最后再重点说下 postForLocation 方法。
postForEntity
在 POST 请求中,参数的传递可以是 key/value 的形式,也可以是 JSON 数据,分别来看:
传递 key/value 形式的参数
首先在 provider 的 HelloController 类中再添加一个 POST 请求的接口,如下:
@PostMapping("/hello2")
public String sayHello2(String name) {
return “Hello " + name + " !”;
}
然后在 consumer 中添加相应的方法去访问,如下:
@GetMapping("/hello5")
public String hello5(String name) {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/hello2”;
MultiValueMap map = new LinkedMultiValueMap();
map.add(“name”, name);
ResponseEntity responseEntity = restTemplate.postForEntity(url, map, String.class);
return responseEntity.getBody();
}
在这里, postForEntity 方法第一个参数是请求地址,第二个参数 map 对象中存放着请求参数 key/value,第三个参数则是返回的数据类型。当然这里的第一个参数 url 地址也可以换成一个 Uri 对象,效果是一样的。这种方式传递的参数是以 key/value 形式传递的,在 post 请求中,也可以按照 get 请求的方式去传递 key/value 形式的参数,传递方式和 get 请求的传参方式基本一致,例如下面这样:
@GetMapping("/hello6")
public String hello6(String name) {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/hello2?name={1}”;
ResponseEntity responseEntity = restTemplate.postForEntity(url, null, String.class,name);
return responseEntity.getBody();
}
此时第二个参数可以直接传一个 null。
传递 JSON 数据
上面介绍的是 post 请求传递 key/value 形式的参数,post 请求也可以直接传递 json 数据,在 post 请求中,可以自动将一个对象转换成 json 进行传输,数据到达 provider 之后,再被转换为一个对象。具体操作步骤如下:
首先在 RestTemplate 项目中创建一个新的maven项目,叫做 commons ,然后在 commons 中创建一个 User 对象,如下:
public class User {
private String username;
private String address;
//省略getter/setter
}
然后分别在 provider 和 consumer 的 pom.xml 文件中添加对 commons 模块的依赖,如下:
com.justdojava commons 1.0-SNAPSHOT这样,在 provider 和 consumer 中就都能使用 User 对象了。首先在 provider 中创建一个添加用户的接口,如下:
@Controller
@ResponseBody
public class UserController {
@PostMapping("/user")
public User hello(@RequestBody User user) {
return user;
}
}
这里的接口很简单,只需要将用户传来的 User 对象再原封不动地返回去就行了,然后在 consumer 中添加一个接口来测试这个接口,如下:
@GetMapping("/hello7")
public User hello7() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/user”;
User u1 = new User();
u1.setUsername(“牧码小子”);
u1.setAddress(“深圳”);
ResponseEntity responseEntity = restTemplate.postForEntity(url, u1, User.class);
return responseEntity.getBody();
}
看到这段代码有人要问了,这不和前面的一样吗?是的,唯一的区别就是第二个参数的类型不同,这个参数如果是一个 MultiValueMap 的实例,则以 key/value 的形式发送,如果是一个普通对象,则会被转成 json 发送。
postForObject
postForObject 和 postForEntity 基本一致,就是返回类型不同而已,这里不再赘述。
postForLocation
postForLocation 方法的返回值是一个 Uri 对象,因为 POST 请求一般用来添加数据,有的时候需要将刚刚添加成功的数据的 URL 返回来,此时就可以使用这个方法,一个常见的使用场景如用户注册功能,用户注册成功之后,可能就自动跳转到登录页面了,此时就可以使用该方法。例如在 provider 中提供一个用户注册接口,再提供一个用户登录接口,如下:
@RequestMapping("/register")
public String register(User user) throws UnsupportedEncodingException {
return “redirect:/loginPage?username=” + URLEncoder.encode(user.getUsername(),“UTF-8”) + “&address=” + URLEncoder.encode(user.getAddress(),“UTF-8”);
}
@GetMapping("/loginPage")
@ResponseBody
public String loginPage(User user) {
return “loginPage:” + user.getUsername() + “:” + user.getAddress();
}
这里一个注册接口,一个是登录页面,不过这里的登录页面我就简单用一个字符串代替了。然后在 consumer 中来调用注册接口,如下:
@GetMapping("/hello8")
public String hello8() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/register”;
MultiValueMap map = new LinkedMultiValueMap();
map.add(“username”, “牧码小子”);
map.add(“address”, “深圳”);
URI uri = restTemplate.postForLocation(url, map);
String s = restTemplate.getForObject(uri, String.class);
return s;
}
这里首先调用 postForLocation 获取 Uri 地址,然后再利用 getForObject 请求 Uri,结果如下:
注意:postForLocation 方法返回的 Uri 实际上是指响应头的 Location 字段,所以,provider 中 register 接口的响应头必须要有 Location 字段(即请求的接口实际上是一个重定向的接口),否则 postForLocation 方法的返回值为null,初学者很容易犯这个错误,如果这里出错,大家可以参考下我的源代码。
PUT 请求
只要将 GET 请求和 POST 请求搞定了,接下来 PUT 请求就会容易很多了,PUT 请求本身方法也比较少,只有三个,如下:
这三个重载的方法其参数其实和 POST 是一样的,可以用 key/value 的形式传参,也可以用 JSON 的形式传参,无论哪种方式,都是没有返回值的,我这里就举两个例子给大家参考下:
首先在 provider 的 UserController 中添加如下两个数据更新接口:
@PutMapping("/user/name")
@ResponseBody
public void updateUserByUsername(User User) {
System.out.println(User);
}
@PutMapping("/user/address")
@ResponseBody
public void updateUserByAddress(@RequestBody User User) {
System.out.println(User);
}
这里两个接口,一个接收 key/value 形式的参数,另一个接收 JSON 参数。因为这里没有返回值,我直接把数据打印出来就行了。接下来在 consumer 中添加接口调用这里的服务,如下:
@GetMapping("/hello9")
public void hello9() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url1 = “http://” + host + “:” + port + “/user/name”;
String url2 = “http://” + host + “:” + port + “/user/address”;
MultiValueMap map = new LinkedMultiValueMap();
map.add(“username”, “牧码小子”);
map.add(“address”, “深圳”);
restTemplate.put(url1, map);
User u1 = new User();
u1.setAddress(“广州”);
u1.setUsername(“江南一点雨”);
restTemplate.put(url2, u1);
}
访问 /hello9 接口,即可看到 provider 上有日志打印出来,这里比较简单,我就不再演示。
DELETE 请求
和 PUT 请求一样,DELETE 请求也是比较简单的,只有三个方法,如下:
图片描述
不同于 POST 和 PUT ,DELETE 请求的参数只能在地址栏传送,可以是直接放在路径中,也可以用 key/value 的形式传递,当然,这里也是没有返回值的。我也举两个例子:
首先在 provider 的 UserController 中添加两个接口,如下:
@DeleteMapping("/user/{id}")
@ResponseBody
public void deleteUserById(@PathVariable Integer id) {
System.out.println(id);
}
@DeleteMapping("/user/")
@ResponseBody
public void deleteUserByUsername(String username) {
System.out.println(username);
}
两个接口,一个的参数在路径中,另一个的参数以 key/value 的形式传递,然后在 consumer 中,添加一个方法调用这两个接口,如下:
@GetMapping("/hello10")
public void hello10() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url1 = “http://” + host + “:” + port + “/user/{1}”;
String url2 = “http://” + host + “:” + port + “/user/?username={username}”;
Map<String,String> map = new HashMap<>();
map.put(“username”, “牧码小子”);
restTemplate.delete(url1, 99);
restTemplate.delete(url2, map);
}
这里参数的传递和 GET 请求基本一致,我就不再赘述了。
其他
设置请求头
有的时候我们会有一些特殊的需求,例如模拟 cookie ,此时就需要我们自定义请求头了。自定义请求头可以通过拦截器的方式来实现(下篇文章我们会详细的说这个拦截器)。定义拦截器、自动修改请求数据、一些身份认证信息等,都可以在拦截器中来统一处理。具体操作步骤如下:
首先在 provider 中定义一个接口,在接口中获取客户端传来的 cookie 数据,如下:
@GetMapping("/customheader")
public String customHeader(HttpServletRequest req) {
return req.getHeader(“cookie”);
}
这里简单处理,将客户端传来的 cookie 拿出来后再返回给客户端,然后在 consumer 中添加如下接口来测试:
@GetMapping("/hello11")
public void hello11() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/customheader”;
restTemplate.setInterceptors(Collections.singletonList(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
HttpHeaders headers = request.getHeaders();
headers.add(“cookie”,“justdojava”);
return execution.execute(request,body);
}
}));
String s = restTemplate.getForObject(url, String.class);
System.out.println(s);
}
这里通过调用 RestTemplate 的 setInterceptors 方法来给它设置拦截器,拦截器也可以有多个,我这里只有一个。在拦截器中,将请求拿出来,给它设置 cookie ,然后调用 execute 方法让请求继续执行。此时,在 /customheader 接口中,就能获取到 cookie了。
通用方法 exchange
在 RestTemplate 中还有一个通用的方法 exchange。为什么说它通用呢?因为这个方法需要你在调用的时候去指定请求类型,即它既能做 GET 请求,也能做 POST 请求,也能做其它各种类型的请求。如果开发者需要对请求进行封装,使用它再合适不过了,举个简单例子:
@GetMapping("/hello12")
public void hello12() {
List list = discoveryClient.getInstances(“provider”);
ServiceInstance instance = list.get(0);
String host = instance.getHost();
int port = instance.getPort();
String url = “http://” + host + “:” + port + “/customheader”;
HttpHeaders headers = new HttpHeaders();
headers.add(“cookie”,“justdojava”);
HttpEntity<MultiValueMap<String,String>> request = new HttpEntity<>(null,headers);
ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
System.out.println(responseEntity.getBody());
}
这里的参数和前面的也都差不多,注意就是多了一个请求类型的参数,然后创建一个 HttpEntity 作为参数来传递。 HttpEntity 在创建时候需要传递两个参数,第一个上文给了一个 null ,这个参数实际上就相当于 POST/PUT 请求中的第二个参数,有需要可以自行定义。HttpEntity 创建时的第二个参数就是请求头了,也就是说,如果使用 exchange 来发送请求,可以直接定义请求头,而不需要使用拦截器。
小结
本文主要向大家介绍了 RestTemplate 这样一个 HTTP 请求工具类的常见用法,一些比较冷门的用法本文并未涉及,读者有兴趣可以自行查找资料学习。由于 Spring、SpringMVC、Spring Boot、Spring Cloud 这些家族成员一脉相承,因此在 SpringMVC 中支持良好的 RESTful 风格的接口在后续的各个组件中都继续支持,在微服务接口设计时,大部分接口也都满足 RESTful 风格,使用 RestTemplate 则可以非常方便地发送 RESTful 风格的请求,因此这个工具的使用是我们后面学习的基础,常见的用法一定要熟练掌握。
进一步RestTemplate 详细操作解释## 详解 RestTemplate 操作
作为开发人员,我们经常关注于构建伟大的软件来解决业务问题。数据只是软件完成工作时
要处理的原材料。但是如果你问一下业务人员,数据和软件谁更重要的话,他们很可能会选择
数据。数据是许多业务的生命之血。软件通常是可以替换的,但是多年积累的数据是永远不能
替换的。
近几年来,以信息为中心的表述性状态转移(Representational State Transfer,REST)已经称为替代传统SOAP Web 服务的流行方案.
SOAP关注的一般是行为和处理,而REST关注的是要处理的数据.
从Spring3.0开始,Spring为创建Rest API提供了良好的支持.
REST提供了一个更简单的可选方案。另外,很多的现代化应用都会有移动或富JavaScript客户端,它们都会使用运行在服务器上REST API。
REST的基础知识
参考我的这篇文章: Restful API 设计指南
当谈论REST时,有一种常见的错误就是将其视为“基于URL的Web服务”——将REST作为另一
种类型的远程过程调用(remote procedure call,RPC)机制,就像SOAP一样,只不过是通过简单
的HTTP URL来触发,而不是使用SOAP大量的XML命名空间
恰好相反,REST与RPC几乎没有任何关系。RPC是面向服务的,并关注于行为和动作;而REST
是面向资源的,强调描述应用程序的事物和名词。
更简洁地讲,REST就是将资源的状态以最适合客户端或服务端的形式从服务器端转移到客户
端(或者反过来)。
在REST中,资源通过URL进行识别和定位。至于RESTful URL的结构并没有严格的规则,但是
URL应该能够识别资源,而不是简单的发一条命令到服务器上。再次强调,关注的核心是事
物,而不是行为。
Spring 中如何使用Rest资源
借助 RestTemplate,Spring应用能够方便地使用REST资源
Spring的 RestTemplate访问使用了模版方法的设计模式.
模版方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了接口的不同行为.
RestTemplate定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。
其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。
delete() 在特定的URL上对资源执行HTTP DELETE操作
exchange()
在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中
映射得到的
execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
postForEntity()
POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得
到的
postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
postForLocation() POST 数据到一个URL,返回新创建资源的URL
put() PUT 资源到特定的URL
实际上,由于Post 操作的非幂等性,它几乎可以代替其他的CRUD操作.
Get请求
RestTemplate 的get方法有以上几个,可以分为两类: getForEntity() 和 getForObject()
首先看 getForEntity() 的返回值类型 ResponseEntity
ResponseEntity getForEntity()
1
看一下 ResponseEntity 的文档描述:
可以看到 它继承了HttpEntity. 封装了返回的响应信息,包括 响应状态,响应头 和 响应体.
在测试之前我们首先 创建一个Rest服务,模拟提供Rest数据,这里给出Controller层代码,具体可以查看源码,文章最后会给出:
/**
-
@author itguang
-
@create 2017-12-17 10:37
**/
@RestController
public class UserController {@Autowired
private UserService userService;@RequestMapping(value = “getAll”)
public List getUser() {
List list = userService.getAll();
return list;
}@RequestMapping(“get/{id}”)
public UserEntity getById(@PathVariable(name = “id”) String id) {return userService.getById(id);
}
@RequestMapping(value = “save”)
public String save(UserEntity userEntity) {return "保存成功";
}
@RequestMapping(value = “saveByType/{type}”)
public String saveByType(UserEntity userEntity,@PathVariable(“type”)String type) {return "保存成功,type="+type;
}
}
测试: getForEntity
无参数的 getForEntity 方法
@RequestMapping(“getForEntity”)
public List getAll2() {
ResponseEntity responseEntity = restTemplate.getForEntity(“http://localhost/getAll”, List.class);
HttpHeaders headers = responseEntity.getHeaders();
HttpStatus statusCode = responseEntity.getStatusCode();
int code = statusCode.value();
List<UserEntity> list = responseEntity.getBody();
System.out.println(list.toString());
return list;
}
有参数的 getForEntity 请求,参数列表,可以使用 {} 进行url路径占位符
//有参数的 getForEntity 请求,参数列表
@RequestMapping(“getForEntity/{id}”)
public UserEntity getById2(@PathVariable(name = “id”) String id) {
ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, id);
UserEntity userEntity = responseEntity.getBody();
return userEntity;
}
有参数的 get 请求,使用map封装参数
//有参数的 get 请求,使用map封装参数
@RequestMapping("getForEntity/{id}")
public UserEntity getById4(@PathVariable(name = "id") String id) {
HashMap<String, String> map = new HashMap<>();
map.put("id",id);
ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, map);
UserEntity userEntity = responseEntity.getBody();
return userEntity;
}
通过断点调试我们看下 返回的 responseEntity 的信息如图:
因此我们可以获取Http请求的全部信息.
但是,通常情况下我们并不想要Http请求的全部信息,只需要相应体即可.对于这种情况,RestTemplate提供了 getForObject() 方法用来只获取 响应体信息.
getForObject 和 getForEntity 用法几乎相同,指示返回值返回的是 响应体,省去了我们 再去 getBody() .
测试: getForObject
无参数的 getForObject 请求
//无参数的 getForObject 请求
@RequestMapping("getAll2")
public List<UserEntity> getAll() {
List<UserEntity> list = restTemplate.getForObject("http://localhost/getAll", List.class);
System.out.println(list.toString());
return list;
}
有参数的 getForObject 请求,使用参数列表
//有参数的 getForObject 请求
@RequestMapping("get2/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) {
UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, id);
return userEntity;
}
有参数的 get 请求,使用map封装请求参数
//有参数的 get 请求,使用map封装请求参数
@RequestMapping("get3/{id}")
public UserEntity getById3(@PathVariable(name = "id") String id) {
HashMap<String, String> map = new HashMap<>();
map.put("id",id);
UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, map);
return userEntity;
}
Post请求
了解了get请求后,Post请求就变得很简单了,我们可以看到post有如下方法:
测试: postForEntity
post 请求,保存 UserEntity 对像
//post 请求,提交 UserEntity 对像
@RequestMapping("saveUser")
public String save(UserEntity userEntity) {
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/save", userEntity, String.class);
String body = responseEntity.getBody();
return body;
}
浏览器访问: http://localhost/saveUser?username=itguang&password=123456&age=20&email=123@123.com
我们再次断点调试,查看 responseEntity 中的信息:
有参数的 postForEntity 请求
// 有参数的 postForEntity 请求
@RequestMapping(“saveUserByType/{type}”)
public String save2(UserEntity userEntity,@PathVariable(“type”)String type) {
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class, type);
String body = responseEntity.getBody();
return body;
}
// 有参数的 postForEntity 请求,使用map封装
@RequestMapping("saveUserByType2/{type}")
public String save3(UserEntity userEntity,@PathVariable("type")String type) {
HashMap<String, String> map = new HashMap<>();
map.put("type", type);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class,map);
String body = responseEntity.getBody();
return body;
}
我们浏览器访问: localhost/saveUserByType/120?username=itguang&password=123456&age=20&email=123@123.com
就会返回: 保存成功,type=120
对与其它请求方式,由于不常使用,所以这里就不再讲述
参考文章
更多相关知识和参考文章来源可以关注我的博客站点