3.4、下载小文件
接口代码如下,这个接口会下载服务器端的 1.txt 文件。
/** * 下载文件 * * @return */ @GetMapping("/test/downFile") @ResponseBody public HttpEntity<InputStreamResource> downFile() { //将文件流封装为InputStreamResource对象 InputStream inputStream = this.getClass().getResourceAsStream("/1.txt"); InputStreamResource inputStreamResource = new InputStreamResource(inputStream); //设置header MultiValueMap<String, String> headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=1.txt"); HttpEntity<InputStreamResource> httpEntity = new HttpEntity<>(inputStreamResource); return httpEntity; }
使用 RestTemplate 调用这个接口,代码如下,目前这个文件的内容比较少,可以直接得到一个数组。
@Test public void test6() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/chat16/test/downFile"; //文件比较小的情况,直接返回字节数组 ResponseEntity<byte[]> responseEntity = restTemplate.getForEntity(url, byte[].class); //获取文件的内容 byte[] body = responseEntity.getBody(); String content = new String(body); System.out.println(content); }
注意:如果文件大的时候,这种方式就有问题了,会导致 oom,要用下面的方式了。
3.5、下载大文件
接口代码,继续使用上面下载 1.txt 的代码
/** * 下载文件 * * @return */ @GetMapping("/test/downFile") @ResponseBody public HttpEntity<InputStreamResource> downFile() { //将文件流封装为InputStreamResource对象 InputStream inputStream = this.getClass().getResourceAsStream("/1.txt"); InputStreamResource inputStreamResource = new InputStreamResource(inputStream); //设置header MultiValueMap<String, String> headers = new HttpHeaders(); headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=1.txt"); HttpEntity<InputStreamResource> httpEntity = new HttpEntity<>(inputStreamResource); return httpEntity; }
此时使用 RestTemplate 调用这个接口,代码如下
文件比较大的时候,比如好几个 G,就不能返回字节数组了,会把内存撑爆,导致 OOM,需要使用 execute 方法了,这个方法中有个 ResponseExtractor 类型的参数,restTemplate 拿到结果之后,会回调{@link ResponseExtractor#extractData}这个方法,在这个方法中可以拿到响应流,然后进行处理,这个过程就是变读边处理,不会导致内存溢出
@Test public void test7() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/chat16/test/downFile"; /** * 文件比较大的时候,比如好几个G,就不能返回字节数组了,会把内存撑爆,导致OOM * 需要这么玩: * 需要使用execute方法了,这个方法中有个ResponseExtractor类型的参数, * restTemplate拿到结果之后,会回调{@link ResponseExtractor#extractData}这个方法, * 在这个方法中可以拿到响应流,然后进行处理,这个过程就是变读边处理,不会导致内存溢出 */ String result = restTemplate.execute(url, HttpMethod.GET, null, new ResponseExtractor<String>() { @Override public String extractData(ClientHttpResponse response) throws IOException { System.out.println("状态:"+response.getStatusCode()); System.out.println("头:"+response.getHeaders()); //获取响应体流 InputStream body = response.getBody(); //处理响应体流 String content = IOUtils.toString(body, "UTF-8"); return content; } }, new HashMap<>()); System.out.println(result); }
3.6、传递头
接口代码
@GetMapping("/test/header") @ResponseBody public Map<String, List<String>> header(HttpServletRequest request) { Map<String, List<String>> header = new LinkedHashMap<>(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration<String> values = request.getHeaders(name); List<String> list = new ArrayList<>(); while (values.hasMoreElements()) { list.add(values.nextElement()); } header.put(name, list); } return header; }
使用 RestTemplate 调用接口,请求头中传递数据,代码如下,注意代码①和②
,这两处是关键,用到了HttpHeaders
和RequestEntity
- 请求头放在 HttpHeaders 对象中
- RequestEntity:请求实体,请求的所有信息都可以放在 RequestEntity 中,比如 body 部分、头、请求方式、url 等信息
@Test public void test8() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/chat16/test/header"; //①:请求头放在HttpHeaders对象中 MultiValueMap<String, String> headers = new HttpHeaders(); headers.add("header-1", "V1"); headers.add("header-2", "Spring"); headers.add("header-2", "SpringBoot"); //②:RequestEntity:请求实体,请求的所有信息都可以放在RequestEntity中,比如body部分、头、请求方式、url等信息 RequestEntity requestEntity = new RequestEntity( null, //body部分数据 headers, //头 HttpMethod.GET,//请求方法 URI.create(url) //地址 ); ResponseEntity<Map<String, List<String>>> responseEntity = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<Map<String, List<String>>>() { }); Map<String, List<String>> result = responseEntity.getBody(); System.out.println(result); }
输出
{accept=[application/json, application/*+json], header-1=[V1], header-2=[Spring, SpringBoot], user-agent=[Java/1.8.0_121], host=[localhost:8080], connection=[keep-alive]}
3.7、综合案例:含头、url 动态参数
接口
@GetMapping("/test/getAll/{path1}/{path2}") @ResponseBody public Map<String, Object> getAll(@PathVariable("path1") String path1, @PathVariable("path2") String path2, HttpServletRequest request) { Map<String, Object> result = new LinkedHashMap<>(); result.put("path1", path1); result.put("path2", path2); //头 Map<String, List<String>> header = new LinkedHashMap<>(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration<String> values = request.getHeaders(name); List<String> list = new ArrayList<>(); while (values.hasMoreElements()) { list.add(values.nextElement()); } header.put(name, list); } result.put("header", header); return result; }
如下,使用 RestTemplate 调用接口,GET 方式、传递 header、path 中动态参数。
@Test public void test9() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/chat16/test/getAll/{path1}/{path2}"; //①:请求头 MultiValueMap<String, String> headers = new HttpHeaders(); headers.add("header-1", "V1"); headers.add("header-2", "Spring"); headers.add("header-2", "SpringBoot"); //②:url中的2个参数 Map<String, String> uriVariables = new HashMap<>(); uriVariables.put("path1", "v1"); uriVariables.put("path2", "v2"); //③:HttpEntity:HTTP实体,内部包含了请求头和请求体 HttpEntity requestEntity = new HttpEntity( null,//body部分,get请求没有body,所以为null headers //头 ); //④:使用exchange发送请求 ResponseEntity<Map<String, Object>> responseEntity = restTemplate.exchange( url, //url HttpMethod.GET, //请求方式 requestEntity, //请求实体(头、body) new ParameterizedTypeReference<Map<String, Object>>() { },//返回的结果类型 uriVariables //url中的占位符对应的值 ); Map<String, Object> result = responseEntity.getBody(); System.out.println(result); }
输出
{path1=v1, path2=v2, header={accept=[application/json, application/*+json], header-1=[V1], header-2=[Spring, SpringBoot], user-agent=[Java/1.8.0_121], host=[localhost:8080], connection=[keep-alive]}}