Spring中RestTemplate的使用方法

一、REST
在互联网中,我们会通过请求url来对网络上的资源做增删改查等动作,这里的请求包含两部分:
动词,主要包括增、删、改、查
名词,就是网络中的各种资源
传统的非REST风格的请求方式是把动词和名词全都放在url中。
例如,对设备的操作可能是这样的:
添加设备:http://test/device/add
删除设备:http://test/device/delete
修改设备:http://test/device/modify
查找设备:http://test/device/find
这样就存在一个规范的问题,例如,添加设备这个动作的单词应该是用add还是create?http方法是用GET还是用POST?等等
REST风格的请求方式是用http请求方法表示增删改查动作,而url中只保留名词,也就是对资源位置的描述,这样就避免了动作描述规范的问题。
还是以对设备的操作举例,REST风格的请求是这样的:
添加设备:http://test/device 请求方法是POST
删除设备:http://test/device 请求方法是DELETE
修改设备:http://test/device 请求方法是PUT
查找设备:http://test/device/:id 请求方法是GET

二、Spring中对REST请求的处理
Spring中可以使用RestTemplate来操作REST资源,主要包含以下几个方法:
getForEntity(),getForObject(),发送HTTP GET请求,getForEntity()返回的是ResponseEntity对象,里面包含响应实体对象及响应状态码,而getForObject()则直接返回响应实体对象
postForEntity(),postForObject(),发送HTTP POST请求,postForEntity()返回的是ResponseEntity对象,里面包含响应实体对象及响应状态码,而postForObject()则直接返回响应实体对象
put(),发送HTTP PUT请求
delete(),发送HTTP DELETE请求
exchange(),可以发送GET、POST、PUT和DELETE中的任意一种请求,同时还可以自定义请求头

下面举例说明几种方法的用法
首先创建一个实体类Device,后面的方法会用到这个实体类

public class Device {
  private String ip;
  private String mac;
}

创建一个用于测试的Controller类

@RestController
@RequestMapping(value = "/consumer")
public class ConsumerController {

  private RestTemplate restTemplate = new RestTemplate();

  private String urlPrefix = "http://localhost:8080/test/producer";
  
  // ...
}

1. GET请求
GET请求有两组重载方法:
1.1 getForEntity()
这个方法有多个重载方法
方法一:
getForEntity(String url, Class<T> responseType, Object... uriVariables)
其中,url就是请求的url,responseType是返回的实体类类型,uriVariables是uri或请求参数

代码示例如下:

  @RequestMapping(value = "/get1")
  public String testGetForEntity1() {
    String url = urlPrefix + "/get";
    ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class);
    System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
    return response.getBody().toString();
  }

返回的response中既包含返回的实体对象(通过response.getBody()获取),又包含返回状态码(通过response.getStatusCodeValue()获取)
这里的url中没有任何参数,所以uriVariables为空。如果url中需要传一些参数,可以通过以下方式传递:

  @RequestMapping(value = "/get2")
  public String testGetForEntity3() {
    String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
    ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class, "NBIot", "ChinaMobile");
    System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
    return response.getBody().toString();
  }

这里传了两个参数protocol和operator

方法二:

getForEntity(String url, Class<T> responseType, Map<String,?> uriVariables)

这种方法是将uriVariables用Map方式传入,如果参数比较多的话,这种方式方便方法之间的参数传递
代码示例如下:

  @RequestMapping(value = "/get3")
  public String testGetForEntity2() {
    Map<String, String> classifyMap = new HashMap<>();
    classifyMap.put("protocol", "NBIot");
    classifyMap.put("operator", "ChinaMobile");
    String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
    ResponseEntity<Device> response = restTemplate.getForEntity(url, Device.class, classifyMap);
    System.out.println("Device: " + response.getBody() + ", code: " + response.getStatusCodeValue());
    return response.getBody().toString();
  }

方法三:

getForEntity(URI url, Class<T> responseType)

这种方法是把String类型的url替换成java.net.URI类型的url

2.2 getForObject()
这个方法和getForEntity()的3个重载方法请求参数是完全一样的,不同的是getForObject()直接返回的是实体对象,而没有返回状态码。如果不关注状态码,只关注返回内容,可以使用这个方法。
方法一:

getForObject(String url, Class<T> responseType, Object... uriVariables)

代码示例如下:
不包含请求参数的方法:

  @RequestMapping(value = "/get4")
  public String testGetForObject1() {
    String url = urlPrefix + "/get";
    Device device = restTemplate.getForObject(url, Device.class);
    System.out.println("Device: " + device);
    return device.toString();
  }

包含请求参数的方法:

  @RequestMapping(value = "/get5")
  public String testGetForObject2() {
    String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
    Device device = restTemplate.getForObject(url, Device.class, "NBIot", "ChinaMobile");
    System.out.println("Device: " + device);
    return device.toString();
  }

方法二:

getForObject(String url, Class<T> responseType, Map<String,?> uriVariables)

代码示例如下:

  @RequestMapping(value = "/get6")
  public String testGetForObject3() {
    Map<String, String> classifyMap = new HashMap<>();
    classifyMap.put("protocol", "NBIot");
    classifyMap.put("operator", "ChinaMobile");
    String url = urlPrefix + "/get?protocol={protocol}&operator={operator}";
    Device device = restTemplate.getForObject(url, Device.class, classifyMap);
    System.out.println("Device: " + device);
    return device.toString();
  }

方法三:

getForObject(URI url, Class<T> responseType)

  

猜你喜欢

转载自www.cnblogs.com/lasdaybg/p/10180201.html