使用Feign实现文件下载

      之前一直也没用Feign做过文件下载,文件上传倒是做过,以往都是只返回文件在服务器上地址,再由服务消费者或者客户端去下载,但这两天在做将activiti做成服务,而做过activiti的都知道,流程模型的bpmn.xml文件和图片都是以BLOB存在数据库,所以必须由服务提供者将文件传给客户端。在网上查了一番,发现几乎没有feign做文件下载的博客大哭,想想也是,一般也不会有人这样做。尝试了使用Inputstream以及feign提供的Response类,都没有成功,后来按照springmvc做下载的方式,使用了spring提供的ResponseEntity,居然就可以了。

       服务提供的代码:

@GetMapping(value = "/api/activiti/process/resource/read/{resType}/{id}")
    public ResponseEntity<byte[]> resourceRead(@PathVariable("resType") String resType, @PathVariable("id") String id) {
		ResponseEntity<byte[]> entity = null;
		HttpHeaders headers = new HttpHeaders();
		ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
        String resourceName = "";
        if (resType.equals("image")) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if (resType.equals("xml")) {
            resourceName = processDefinition.getResourceName();
        }
		try {
			InputStream resourceAsStream = processService.resourceRead(id,resType);
			byte[] b = new byte[resourceAsStream.available()];
			resourceAsStream.read(b);
			headers.add("Content-Disposition", "attachment;filename="+resourceName);
			HttpStatus status = HttpStatus.OK;
			resourceAsStream.close();
			entity = new ResponseEntity<byte[]>(b, headers, status);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return entity;
	}

中间关于activiti的代码可以忽略,主要是try-catch中的代码,在拿到文件的输入流(InputStream)之后,将文件写入到定义的byte[]数组中,再设置httpheader,设置为带有附件,最后返回ResponseEntity<byte[]>对象,客户端拿到这个对象后直接返回即可,就可以下载activiti模型的xml或png文件。

       我觉得使用feign实现文件下载的场景并不常见,尤其万一要是文件较大,很容易引起feign超时的问题,所以对于这种activiti的情况,使用倒也没啥问题,但其他情况还是应该返回给消费者或客户端文件的URL比较好,由专门的文件服务器、CDN来做。

猜你喜欢

转载自blog.csdn.net/wetsion/article/details/80012823