一、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)
原文地址:https://www.cnblogs.com/lasdaybg/p/10180201.html