这里写目录标题
一、介绍
RestTemplate
是从 Spring3.0 开始支持的一个 HTTP
请求工具,它提供了常见的REST请求方案的模版,例如 GET
请求、POST
请求、PUT
请求、DELETE
请求以及一些通用的请求执行方法 exchange
以及 execute
。
二、GET 请求
getForEntity
和 getForObject
,每一类有三个重载方法
getForObject
getForEntity 方法:第一个参数是 url
,url 中有一个占位符 {1}
,如果有多个占位符分别用 {2} 、 {3} … 去表示,第二个参数是接口返回的数据类型
例如返回的String
类型,最后是一个可变长度的参数,用来给占位符填值。
这里参数的传递
除了这一种方式之外,还有另外两种方式,也就是 getForEntity
方法的另外两个重载方法。
使用Map
来传递参数:
注意:URL中的占位符不是用{1}
数字来占位,而是使用Map
的key
来占用。
还有一个是使用 Uri
对象,使用 Uri 对象时,参数可以直接拼接在地址中:
//第三种 URI,参数直接拼接 http://localhost:9000/account/get?name=zhangsan&age=18
URI uri = URI.create("http://localhost:9000/account/get?name=zhangsan&age=18");
String forObject = restTemplate.getForObject(uri, String.class);
getForEntity
如果开发者需要获取响应头的话,那么就需要使用 getForEntity
来发送 HTTP 请求,此时返回的对象是一个 ResponseEntity
的实例。这个实例中包含了响应数据以及响应头。在返回的 ResponseEntity
中,可以获取响应头中的信息,其中 getStatusCode
方法用来获取响应状态码, getBody
方法用来获取响应数据, getHeaders
方法用来获取响应头。
另外两个方法是和getForObject
一样的。
三、POST 请求
postForEntity
key/value格式
在 POST
请求中,参数的传递可以是 key/value
的形式,也可以是 JSON
数据。
postForEntity 方法第一个参数是请求地址,第二个参数 map 对象中存放着请求参数 key/value,第三个参数则是返回的数据类型。当然这里的第一个参数 url 地址也可以换成一个 Uri 对象,效果是一样的。这种方式传递的参数是以 key/value 形式传递的
在 post 请求中,也可以按照 get 请求的方式去传递 key/value 形式的参数,传递方式和 get 请求的传参方式基本一致:(即Post请求也可以使用?
和&
拼接参数),此时第二个参数可以直接传一个 null
。
JSON格式
postForObject
postForObject
和 postForEntity
是一样的,只是返回类型不一样。
postForLocation
postForLocation
方法的返回值是一个 URI
对象,因为 POST 请求一般用来添加数据,有的时候需要将刚刚添加成功的数据的 URL 返回来,此时就可以使用这个方法。
四、PUT 请求
这三个重载的方法其参数其实和 POST 是一样的,可以用 key/value 的形式传参,也可以用 JSON 的形式传参,无论哪种方式,都是没有返回值的。如果需要返回值,可以使用exchange
方法,获取返回值。
五、DELETE 请求
不同于 POST 和 PUT ,DELETE 请求的参数只能在地址栏传送,可以是直接放在路径中,也可以用 key/value 的形式传递,当然,这里也是没有返回值的。
参数的传递和 GET 请求基本一致。
exchange 通用方法
这个方法需要你在调用的时候去指定请求类型,即它既能做 GET 请求,也能做 POST 请求,也能做其它各种类型的请求。如果开发者需要对请求进行封装,使用它再合适不过了。
参数和前面的也都差不多,注意就是多了一个请求类型
的参数,然后创建一个 HttpEntity
作为参数来传递。 HttpEntity 在创建时候需要传递两个参数,第一个上文给了一个 null
,这个参数实际上就相当于 POST/PUT 请求中的第二个参数
,有需要可以自行定义。HttpEntity
创建时的第二个参数就是请求头
了,也就是说,如果使用 exchange
来发送请求,可以直接定义请求头,而不需要使用拦截器。
public ResultObject exchande(){
String name = "zhangsan";
Integer age = 23;
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("name",name);
hashMap.put("age",age);
MultiValueMap<String, Object> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add("name",name);
multiValueMap.add("age",age);
//构造请求头
HttpHeaders headers = new HttpHeaders();
headers.add("username","ZhangSan");
// GET
String url1 = "http://localhost:9000/account/get?name={1}&age={2}";
//构造请求体 第一个参数实际上就相当于 POST/PUT 请求中的第二个参数;第二个参数是请求头
HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(null,headers);
ResponseEntity<String> exchange = restTemplate.exchange(url1, HttpMethod.GET, httpEntity, String.class,name,age);
// POST 请求 key/value格式
String url2 = "http://localhost:9000/account/postKeyValue";
HttpEntity<MultiValueMap<String, Object>> httpEntity2 = new HttpEntity<>(multiValueMap,headers);
ResponseEntity<String> exchange2 = restTemplate.exchange(url2, HttpMethod.POST, httpEntity2, String.class);
// POST 请求 JSON格式
String url3 = "http://localhost:9000/account/postJson";
HttpEntity<Map<String, Object>> httpEntity3 = new HttpEntity<>(hashMap,headers);
ResponseEntity<String> exchange3 = restTemplate.exchange(url3, HttpMethod.POST, httpEntity3, String.class);
// PUT key/value
String url4= "http://localhost:9000/account/putKeyValue";
ResponseEntity<String> exchange4 = restTemplate.exchange(url4, HttpMethod.PUT, httpEntity2,String.class);
// PUT JSON
String url5= "http://localhost:9000/account/putJson";
ResponseEntity<String> exchange5 = restTemplate.exchange(url5, HttpMethod.PUT, httpEntity3,String.class);
//DELETE
String url6 = "http://localhost:9000/account/del?name={name}&age={age}";
HttpEntity<Map<String, Object>> httpEntity6 = new HttpEntity<>(null,headers);
ResponseEntity<String> exchange6 = restTemplate.exchange(url6, HttpMethod.DELETE, httpEntity3, String.class,hashMap);
System.out.println("body : "+exchange.getBody());
System.out.println("statusCode : "+exchange.getStatusCode());
System.out.println("statusCodeValue : "+exchange.getStatusCodeValue());
System.out.println("Headers : "+exchange.getHeaders());
return new ResultObject(true,0000,"restTemplate.exchange",exchange.getBody());
}
六、文件上传
使用RestTemplate对象请求文件上传接口。使用Rest Template上传文件时,不能使用File
类型或是直接使用MulitiTypeFile
类型来作为参数。
//将MultipartFile格式文件转换为File文件 FileUtils为commons-io工具类
FileUtils.copyInputStreamToFile(data.getInputStream(),file);
File thumFile = new File(thumFilePath);
FileSystemResource thumFileSystemResource = new FileSystemResource(thumFile);
LinkedMultiValueMap thumForm = new LinkedMultiValueMap();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
thumForm.add("data",thumFileSystemResource);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(thumForm, headers);
String respones1 = restTemplate.postForObject(url, httpEntity, String.class);
七、文件下载
使用RestTemplate对象请求文件下载接口。正常情况返回二进制流文件,下载并保存,异常情况返回json文本,提示给前端显示。
所以使用byte[]
类型进行接收。
String replace = downloadFileMsgUrl.replace("{fileName}", msgData.getFileName()).replace("{cpId}",gjmp);
//返回二进制流文件 将二进制写入临时文件
byte[] fielByte = restTemplate.getForObject(replace, byte[].class);
String filePath = tempFilePath+msgData.getFileName();
File file = new File(filePath);
FileUtils.writeByteArrayToFile(file,fielByte);
LinkedMultiValueMap linkedMultiValueMap = new LinkedMultiValueMap();
FileSystemResource thumFileSystemResource = new FileSystemResource(file);
linkedMultiValueMap.add("file",thumFileSystemResource);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<Object> httpEntity = new HttpEntity<>(linkedMultiValueMap, headers);
//上传文件到文件服务器
ResponseEntity<String> responseEntity = restTemplate.exchange(uploadUrl, HttpMethod.PUT, httpEntity, String.class);
String body = responseEntity.getBody();