项目实例:

    @GetMapping("getPermitSignFile")@ApiOperation(value = "获取许可证签名文件")public ResponseEntity<Resource> getPermitSignFile(@ApiParam(name = "permitId", value = "许可证ID") String permitId) throws UnsupportedEncodingException {//判断所要下载的文件ID是否存在!!!//专门有个存图的表在其中查 fileId ,存在才可以下载!!!String fileId = this.service.getPermitSignFileId(permitId);if (!StringUtils.isEmpty(fileId)) {Map<String, Object> file = this.documentService.loadAsResource(fileId);//这种方式返回body 内容!!!ResponseEntity.BodyBuilder ok = ResponseEntity.ok().header("Content-Disposition", new String[]{"attachment; filename= \"" + URLEncoder.encode((String) file.get("fileName"), "UTF-8") + "\""})).body((Resource) file.get("resource"));return ok;}return null;}

解释上文:
ResponseEntity概念是可以添加HttpStatus状态码的HttpEntity的扩展类;那么不难推测出这个OK状态其实就是HttpStatus状态码

//无参ok
public static ResponseEntity.BodyBuilder ok() {return status(HttpStatus.OK);}

HttpStatus状态码中代表OK的是200

BodyBuilder又是什么鬼:

通过ResponseEntity的结构,我们知道BodyBuilder是ResponseEntity中的接口
直译:
定义一个可以添加body到response entity的builder
简单粗暴理解:
ResponseEntity可以通过这个builder返回任意类型的body内容。
BodyBuilder源码:

public interface BodyBuilder extends ResponseEntity.HeadersBuilder<ResponseEntity.BodyBuilder> {ResponseEntity.BodyBuilder contentLength(long var1);ResponseEntity.BodyBuilder contentType(MediaType var1);<T> ResponseEntity<T> body(@Nullable T var1);}

通过BodyBuilder源码,不难发现

BodyBuilder接口中的body方法的参数可以为空值(有@Nullable标签名字推测其允许空值)

loadAsResource 接口(直接用):


public Map<String, Object> loadAsResource(String fileId) {Map<String, Object> result = new HashedMap();FileInfo fileInfo = (FileInfo)this.fileInfoRepository.findOne(fileId);if (fileInfo != null) {String fileName = fileInfo.getFileOriginalName();try {Resource resource = new InputStreamResource(MinioUtil.getInstance().getObjectStream(fileInfo.getFileStorageId()));if (!resource.exists() && !resource.isReadable()) {throw new StorageFileNotFoundException("读取文件失败: " + fileName);} else {result.put("fileName", fileName);result.put("resource", resource);return result;}} catch (MalformedURLException var6) {throw new StorageFileNotFoundException("读取文件失败: " + fileName, var6);} catch (Exception var7) {var7.printStackTrace();throw new StorageFileNotFoundException("读取文件失败: " + fileName, var7);}} else {throw new StorageFileNotFoundException("读取文件失败: " + fileId);}}

Resource(应该可以直接用):

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package org.springframework.core.io;import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;public interface Resource extends InputStreamSource {boolean exists();boolean isReadable();boolean isOpen();URL getURL() throws IOException;URI getURI() throws IOException;File getFile() throws IOException;long contentLength() throws IOException;long lastModified() throws IOException;Resource createRelative(String var1) throws IOException;String getFilename();String getDescription();
}

MinioUtil:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package com.richfit.ip.document.minio;import com.richfit.ip.utils.StringUtil;
import com.richfit.ip.webmvc.SpringContextHelper;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidArgumentException;
import io.minio.errors.InvalidBucketNameException;
import io.minio.errors.NoResponseException;
import io.minio.messages.Item;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmlpull.v1.XmlPullParserException;public class MinioUtil {private static final Logger log = LoggerFactory.getLogger(MinioUtil.class);private static MinioUtil minioUtil;private MinioProperty minioProperty = (MinioProperty)SpringContextHelper.getBean(MinioProperty.class);private MinioClient minioClient;private static int RETRY_NUM = 3;public static MinioUtil getInstance() {if (null != minioUtil) {return minioUtil;} else {Class var0 = MinioUtil.class;synchronized(MinioUtil.class) {if (null == minioUtil) {minioUtil = new MinioUtil();}}return minioUtil;}}private MinioUtil() {if (null == this.minioProperty) {this.minioProperty = new MinioProperty();}this.init();}private void init() {try {if (StringUtils.isNotEmpty(this.minioProperty.getUrl()) && StringUtils.isNotEmpty(this.minioProperty.getAccessKey()) && StringUtils.isNotEmpty(this.minioProperty.getSecretKey())) {this.minioClient = new MinioClient(this.minioProperty.getUrl(), this.minioProperty.getAccessKey(), this.minioProperty.getSecretKey(), false);if (!StringUtil.isNullOrEmpty(this.minioProperty.getDefaultBucketName())) {this.createBucket(this.minioProperty.getDefaultBucketName());}}} catch (Exception var2) {log.error("初始化minio客户端失败:", var2);}}public MinioClient getMinioClient() {return this.minioClient;}public boolean createBucket(String bucketName) {boolean isCreated;try {if (!this.minioClient.bucketExists(bucketName)) {this.minioClient.makeBucket(bucketName);}isCreated = true;} catch (Exception var4) {isCreated = false;log.error("创建Bucket失败", var4);var4.printStackTrace();}return isCreated;}public String uploadStream(String bucketName, String minioFilePath, InputStream inputStream, String mediaType) {if (StringUtils.isBlank(mediaType)) {mediaType = "application/octet-stream";}try {this.putObjectWithRetry(bucketName, minioFilePath, inputStream, mediaType);return this.cleanUrlByRemoveIp(this.minioClient.getObjectUrl(bucketName, minioFilePath));} catch (Exception var6) {log.error("上传文件流发生错误:", var6);throw new RuntimeException(var6);}}public String uploadStream(String minioFilePath, InputStream inputStream, String mediaType) {return this.uploadStream(this.minioProperty.getDefaultBucketName(), minioFilePath, inputStream, mediaType);}public String uploadFile(String minioFilePath, String localFile, String mediaType) {return this.uploadFile(this.minioProperty.getDefaultBucketName(), minioFilePath, localFile, mediaType);}public String uploadFile(String bucketName, String minioFilePath, String localFile, String mediaType) {if (StringUtils.isBlank(mediaType)) {mediaType = "application/octet-stream";}try {this.putObjectWithRetry(bucketName, minioFilePath, localFile, mediaType);return this.cleanUrlByRemoveIp(this.minioClient.getObjectUrl(bucketName, minioFilePath));} catch (Exception var6) {log.error("上传文件发生错误:", var6);throw new RuntimeException(var6);}}public List<MinioFile> listFilesSwap(String bucketName, String prefix, boolean recursive) {return this.swapResultToEntityList(this.minioClient.listObjects(bucketName, prefix, recursive));}public Iterable<Result<Item>> listFiles(String bucketName, String prefix, boolean recursive) {return this.minioClient.listObjects(bucketName, prefix, recursive);}public List<MinioFile> listFilesByBucketNameSwap(String bucketName) {return this.swapResultToEntityList(this.minioClient.listObjects(bucketName, (String)null, true));}public Iterable<Result<Item>> listFilesByBucketName(String bucketName) {return this.minioClient.listObjects(bucketName, (String)null, true);}public Iterable<Result<Item>> listFilesByBucketAndPrefix(String bucketName, String prefix) {return this.minioClient.listObjects(bucketName, prefix, true);}public List<MinioFile> listFilesByBucketAndPrefixSwap(String bucketName, String prefix) {return this.swapResultToEntityList(this.minioClient.listObjects(bucketName, prefix, true));}private MinioFile swapResultToEntity(Result<Item> result) {MinioFile entity = new MinioFile();try {if (result.get() != null) {Item item = (Item)result.get();entity.setObjectName(this.cleanUrlByRemoveIp(item.objectName()));entity.setIsDir(item.isDir());entity.setEtag(item.etag());entity.setLastModified(item.lastModified());entity.setObjectSize(item.objectSize());entity.setStorageClass(item.storageClass());}} catch (Exception var4) {log.error("获取文件信息出错, e={}", var4.getMessage());}return entity;}private String cleanUrlByRemoveIp(String s) {return s;}private List<MinioFile> swapResultToEntityList(Iterable<Result<Item>> results) {List<MinioFile> files = new ArrayList();Iterator var3 = results.iterator();while(var3.hasNext()) {Result<Item> result = (Result)var3.next();files.add(this.swapResultToEntity(result));}return files;}public void putObjectWithRetry(String bucketName, String objectName, InputStream stream, String contentType) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidArgumentException, NoResponseException, InvalidBucketNameException, XmlPullParserException, InternalException {int current = 0;boolean isSuccess = false;while(!isSuccess && current < RETRY_NUM) {try {this.minioClient.putObject(bucketName, objectName, stream, contentType);stream.close();isSuccess = true;} catch (ErrorResponseException var8) {log.warn("[minio] putObject stream, ErrorResponseException occur for time =" + current, var8);++current;}}if (current == RETRY_NUM) {log.error("[minio] putObject, backetName={}, objectName={}, failed finally!");}}public String getObjectUrl(String objectName) throws Exception {return this.getObjectUrl(this.minioProperty.getDefaultBucketName(), objectName, 86400);}public void removeObject(String objectName) throws Exception {this.minioClient.removeObject(this.minioProperty.getDefaultBucketName(), objectName);}public void removeObject(String bucketName, String objectName) throws Exception {this.minioClient.removeObject(bucketName, objectName);}public void removeObjects(String bucketName, List<String> objectNames) throws Exception {this.minioClient.removeObject(bucketName, objectNames);}public void removeObjects(List<String> objectNames) throws Exception {this.minioClient.removeObject(this.minioProperty.getDefaultBucketName(), objectNames);}public String getObjectUrl(String bucketName, String objectName) throws Exception {return this.getObjectUrl(bucketName, objectName, 86400);}public InputStream getObjectStream(String bucketName, String objectName) throws Exception {return this.minioClient.getObject(bucketName, objectName);}public InputStream getObjectStream(String objectName) throws Exception {return this.getObjectStream(this.minioProperty.getDefaultBucketName(), objectName);}public String getObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {return this.minioClient.presignedGetObject(bucketName, objectName, expires);}public void putObjectWithRetry(String bucketName, String objectName, String fileName, String contentType) throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, NoResponseException, XmlPullParserException, ErrorResponseException, InternalException, InvalidArgumentException, InsufficientDataException {int current = 0;boolean isSuccess = false;while(!isSuccess && current < RETRY_NUM) {try {this.minioClient.putObject(bucketName, objectName, fileName, contentType);isSuccess = true;} catch (ErrorResponseException var8) {++current;log.debug("[minio] putObject file, ErrorResponseException occur!");}}if (current == RETRY_NUM) {log.error("[minio] putObject, backetName={}, objectName={}, failed finally!");}}public static void main(String[] args) throws Exception {List<MinioFile> files = getInstance().listFilesByBucketNameSwap("image");String url = getInstance().getObjectUrl("image", ((MinioFile)files.get(0)).getObjectName());}
}
    @RequestMapping("/testResponseEntity")public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException{byte [] body = null;ServletContext servletContext = session.getServletContext();InputStream in = servletContext.getResourceAsStream("/files/abc.txt");body = new byte[in.available()];in.read(body);HttpHeaders headers = new HttpHeaders();headers.add("Content-Disposition", "attachment;filename=abc.txt");HttpStatus statusCode = HttpStatus.OK;ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode);return response;}

其中对Content-Disposition 响应头 进行解析:
在页面内打开代码:

    File file = new File("rfc1806.txt");String filename = file.getName();response.setHeader("Content-Type","text/plain");response.addHeader("Content-Disposition","inline;filename=" + new String(filename.getBytes(),"utf-8"));response.addHeader("Content-Length","" + file.length());

弹出保存框代码:

    File file = new File("rfc1806.txt");String filename = file.getName();response.setHeader("Content-Type","text/plain");response.addHeader("Content-Disposition","attachment;filename=" + new String(filename.getBytes(),"utf-8"));response.addHeader("Content-Length","" + file.length());

ResponseEntity进行下载相关推荐

  1. SpringMVC中文件的上传和下载

    1 文件下载 ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文. 使用ResponseEntity实现下载文件功能 package com.spr ...

  2. SpringMVC通过ResponseEntity实现文件下载

    使用ResponseEntity实现下载文件的功能 所下载的图片路径如图所示: Controller: @RequestMapping("/testDown") public Re ...

  3. 普通文件下载 + 前端获取后端返回的文件流并下载

    参考资料 前端接受后端文件流并下载的几种方法 ajax 请求二进制流 图片 文件 XMLHttpRequest 请求并处理二进制流数据 之最佳实践 ajax请求二进制流进行处理(ajax异步下载文件) ...

  4. SpringMVC处理Json、文件上传、拦截器

    SpringMVC处理Json.文件上传.拦截器 : 处理JSON 链接 http://repo1.maven.org/maven2/com/fasterxml/jackson/core/ 步骤 编写 ...

  5. SpringBoot(2)

    5.Web开发 5.1.SpringMVC自动配置概览 Spring Boot provides auto-configuration for Spring MVC that works well w ...

  6. b站尚硅谷springmvc学习视频:springmvc文档

    文章目录 一.SpringMVC简介 (b站尚硅谷springmvc学习视频:springmvc文档) 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.HelloWo ...

  7. SpringMVC-详解

    文章目录 一.SpringMVC简介 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.HelloWorld 1.开发环境 2.创建maven工程 a>添加web ...

  8. SpringMVC的相关知识

    目录 SpringMVC 一.SpringMVC简介 1.概述 2.特点 二.入门案例 1.创建一个webapp项目 2.导入相关包 3.配置web.xml文件 4.创建请求控制器 5.配置Sprin ...

  9. SpringMVC笔记-尚硅谷(杨博超)

    文章目录 一.SpringMVC简介 1.什么是MVC 2.什么是SpringMVC 3.SpringMVC的特点 二.HelloWorld 1.开发环境 2.创建maven工程 a>添加web ...

最新文章

  1. 【Python】Python3中的str和bytes
  2. 手机端部署的超分机器学习模型-MobiSR
  3. oracle数据库从入门到精通之三
  4. 算法题12 数组中所有的逆序对
  5. smarty二维foreach示例[顺代一维数组],再次加强版
  6. oracle cdc 关闭,Oracle CDC部署流程
  7. css动画详解 (transition animation)
  8. FireMonkey 保存图片到JPG的方法 BMP转JPG
  9. Java-IO流-实例
  10. es6数组初始化_说一下自己常用的es6的功能
  11. 骑士人才系统后台用户名密码重设工具源码
  12. CVE-2015-5254(ActiveMQ反序列化漏洞复现)
  13. 从期货开户公司分享交易所手续费返还
  14. 网页打开慢,甚至突然打不开?图片刷新不出来?多半是DNS的问题!
  15. 只可顺守不可逆取书法_关于如何练字,分享给想练好书法的人
  16. 【回顾】巨杉数据库中标东莞农商银行非结构化内容管理平台项目
  17. 【头歌】重生之机器学习-线性回归
  18. 职称论文发表的字数不够怎么办
  19. 电脑外设(I/O)简介:键盘鼠标
  20. 详细解读《个人所得税专项附加扣除暂行办法》

热门文章

  1. 计算机安装Hp1005打印机,hp1005打印机驱动官方版
  2. 如何用python的turtle画五角星_海龟编辑器五角星怎么画 绘制五角星就是这么简单...
  3. C# WPF 基于Socket的企业聊天软件IM(源码)
  4. 微信里的小程序怎么制作
  5. 【分享】免梯子的GPT,玩 ChatGPT 的正确姿势
  6. 让企业订单交期满足率提升3.5倍,新一代APS(高级生产计划与排程系统)是什么样的?
  7. Spring Boot使用@RepeatSubmit 防止重复提交
  8. fiyme android底层,魅族首批Android 10底层Flyme于今日正式推送
  9. 【Linux 操作系统】Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
  10. css3实现简单的文字动画效果