ResponseEntity进行下载

项目实例:

    @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());
AJAX (Asynchronous JavaScript and XML) 是一种用于创建异步网页应用的技术,允许前端通过JavaScript与服务器进行非阻塞的数据交换。当涉及到从服务器下载文件时,通常会利用`ResponseEntity`这个Spring MVC的概念。 在Spring框架中,`ResponseEntity`是一个泛型类型,可以包含HTTP响应的状态码、headers以及响应体内容,包括流或者是字节数组等。要使用它来下载文件,你可以这样做: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.http.ResponseEntity; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @GetMapping("/download") public ResponseEntity效验文件名及处理下载请求(@RequestParam("file") MultipartFile file) { try { // 检查文件是否有效 if (!file.isEmpty()) { String filename = extractFileName(file); Path targetPath = saveFileToFileSystem(filename, file); // 创建一个Content-Disposition header,模拟浏览器下载行为 HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment", filename); // 使用 ResponseEntity.ok() 和 bytes[] 或者 FileStream来设置响应内容 return ResponseEntity.ok() .headers(headers) .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(Files.readAllBytes(targetPath)); } else { return ResponseEntity.badRequest().build(); // 返回错误状态码 } } catch (IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error downloading file"); } } private String extractFileName(MultipartFile file) { return file.getOriginalFilename(); } private Path saveFileToFileSystem(String fileName, MultipartFile file) throws IOException { byte[] bytes = file.getBytes(); Path filePath = Paths.get("your/download/folder/" + fileName); Files.write(filePath, bytes); return filePath; } ``` 在这个示例中,用户提交文件到 `/download` 路径,服务端检查文件并将其保存到本地,然后返回一个`ResponseEntity`,其中包含了文件数据和适当的HTTP头部信息以启动下载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值