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());
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Spring MVC的ResponseEntity类来下载二进制流。例如: ``` @GetMapping("/download") public ResponseEntity<byte[]> downloadFile() throws IOException { byte[] data = // 获取二进制数据 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", "file.txt"); return new ResponseEntity<>(data, headers, HttpStatus.OK); } ``` 其中,byte[]为二进制数据,headers设置文件类型为二进制流和文件名,HttpStatus.OK表示请求成功。 ### 回答2: 在Spring框架中,可以使用ResponseEntity下载二进制流。ResponseEntity是一个通用的返回对象,它可以包含HTTP响应的状态码、头部信息和响应体。 首先,我们需要使用HttpClient或者RestTemplate发送HTTP请求获取到包含二进制流的响应体。然后,创建一个ResponseEntity对象,将获取到的二进制流设置为响应体,并设置Content-Type和Content-Disposition头部信息。 以下是一个使用RestTemplate下载二进制流的示例代码: ```java RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); // 设置请求头部信息 headers.set(HttpHeaders.CONTENT_TYPE, "application/octet-stream"); headers.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.txt"); // 发送GET请求 ResponseEntity<byte[]> response = restTemplate.exchange("http://example.com/download", HttpMethod.GET, new HttpEntity<>(headers), byte[].class); // 获取响应体 byte[] binaryData = response.getBody(); // 将二进制流保存到本地文件 try (OutputStream outputStream = new FileOutputStream("test.txt")) { outputStream.write(binaryData); outputStream.flush(); System.out.println("文件下载完成"); } catch (IOException e) { e.printStackTrace(); } ``` 以上代码中,我们使用RestTemplate发送一个GET请求,并设置请求头部信息。然后,通过exchange方法获取到响应体的二进制流,并保存到本地文件中。 需要注意的是,需要根据实际情况设置Content-Type和Content-Disposition头部信息,以确保下载的文件可以正确显示和保存。 总结起来,使用ResponseEntity下载二进制流的步骤包括发送HTTP请求获取响应体,创建ResponseEntity对象,将二进制流设置为响应体,并设置头部信息。最后,可以将二进制流保存为文件或者进行其他处理。 ### 回答3: ResponseEntity是Spring框架提供的一个用于封装HTTP响应的类,它可以包含响应的状态码、响应头和响应体等信息。可以通过ResponseEntity下载二进制流。 首先,我们需要创建一个请求地址的URL对象。然后,使用Java的URL.openConnection()方法打开一个连接,并将连接强制转换为HttpURLConnection类型,便于设置请求的参数。 设置连接的请求方法为GET,即发送一个GET请求,获取服务器返回的响应流。然后,可以通过调用连接的getInputStream()方法获取服务器返回的输入流。 接下来,可以创建一个ByteArrayOutputStream对象,用于将输入流中的数据写入到内存中的字节数组中。我们可以创建一个缓冲区变量,每次读取一部分数据,然后将数据写入到ByteArrayOutputStream中,直到数据读取完毕。 最后,将ByteArrayOutputStream中的字节数组作为响应体返回给客户端。可以使用ResponseEntity的静态方法ok()来创建一个成功的响应,设置响应的状态码为200,并将字节数组作为响应体返回。 示例代码如下: ```java import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public ResponseEntity<byte[]> downloadBinaryFile() { try { // 请求地址 String fileUrl = "http://example.com/file.bin"; URL url = new URL(fileUrl); // 打开连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); // 获取输入流 InputStream inputStream = connection.getInputStream(); // 写入字节数组 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } byte[] fileBytes = outputStream.toByteArray(); // 设置响应头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", "file.bin"); // 返回响应实体 return ResponseEntity.ok().headers(headers).body(fileBytes); } catch (Exception e) { e.printStackTrace(); // 返回错误响应 return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } ``` 上述代码可以将指定URL的二进制文件下载,并将文件的字节数组作为响应体返回给客户端。同时,还设置了响应头用于指定文件名称和文件类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值