Java web 下载接口模板:
1、使用HttpServletResponse输出流实现
@GetMapping("/download")
public void bianPdfDownload(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 请求类型、请求参数、请求头 根据需求制定即可
// 获取到需要下载的文件
// 如何生成文件,根据实际业务需求改造即可
String outputFilePath = "/data/file-store-temp/2023年05月13日分析报告.pdf";
log.debug("待下载文件:{}", outputFilePath);
// 下载文件
// 设置响应的内容类型,让浏览器知道下载的是一个文件
ServletContext context = request.getServletContext();
// get MIME type of the file
String mimeType = context.getMimeType(outputFilePath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
log.debug("context getMimeType is null");
}
log.debug("MIME type: " + mimeType);
// 设置响应头信息,告诉浏览器文件的名称和长度
// set content attributes for the response
response.setContentType(mimeType);
response.setContentLength((int) file.length());
// 设置编码
response.setCharacterEncoding("utf-8");
// 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
String headerValue = String.format("attachment; filename=%s",
UriUtils.encode(fileName1, StandardCharsets.UTF_8));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);
// Copy the stream to the response's output stream.
try {
InputStream myStream = new FileInputStream(outputFilePath);
IOUtils.copy(myStream, response.getOutputStream());
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
2、使用ResponseEntity实现
import org.springframework.web.util.UriUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile() throws Exception {
// 请求类型、请求参数、请求头 根据需求制定即可
// 获取到需要下载的文件
// 如何生成文件,根据实际业务需求改造即可
String fileName = "2023年05月13日分析报告.pdf";
String outputFilePath = "/data/file-store-temp/" + fileName;
log.debug("待下载文件:{}", outputFilePath);
Path path = Paths.get(outputFilePath);
Resource resource = null;
try {
resource = new UrlResource(path.toUri());
} catch (MalformedURLException e) {
e.printStackTrace();
}
// 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" +
UriUtils.encode(fileName, StandardCharsets.UTF_8));
//
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
// 返回响应实体,包含文件内容和响应头
return ResponseEntity.ok()
.headers(headers)
.contentLength(resource.contentLength())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
}
其他
这三个 HTTP 响应头都是用来控制浏览器缓存的,具体作用如下:
1. `Cache-Control`: 该响应头用于控制缓存行为,常见的取值有以下几种:
- `no-cache`: 表示不缓存响应内容,每次请求都需要向服务器重新发起请求。
- `no-store`: 表示不缓存响应内容,并且不存储请求和响应的任何部分。
- `max-age`: 表示缓存内容的最大有效时间,单位为秒。例如,`Cache-Control: max-age=3600` 表示缓存内容在 1 小时后过期。
- `private`: 表示响应内容只能被客户端缓存,而不能被中间代理服务器缓存。
- `public`: 表示响应内容可以被客户端和中间代理服务器缓存。
2. `Pragma`: 该响应头用于控制缓存行为,但已经被弃用,现在建议使用 `Cache-Control` 响应头。
- `no-cache`: 与 `Cache-Control: no-cache` 作用相同,表示不缓存响应内容。
3. `Expires`: 该响应头用于指定缓存内容的过期时间,是一个绝对时间,表示一个日期时间值。例如,`Expires: Wed, 21 Oct 2015 07:28:00 GMT` 表示缓存内容在该时间之后过期。
在实际应用中,我们可以根据需要选择适当的缓存策略。例如,如果我们的网站提供的是实时数据,需要保证每次请求都能及时获取最新的数据,可以使用 `Cache-Control: no-cache` 或 `Pragma: no-cache` 响应头来禁用缓存;如果我们的网站提供的是静态资源(例如图片、CSS、JavaScript 文件等),可以使用较长的缓存时间,减少不必要的网络请求,提高页面加载速度,可以使用 `Cache-Control: max-age` 或 `Expires` 响应头来设置缓存时间。
优化,工具类提取
package com.baian.blockchainanalysis.controller;
import com.baian.blockchainanalysis.conf.FileParsingProperties;
import com.baian.blockchainanalysis.pojo.bo.AnalysisResultModelBo;
import com.baian.blockchainanalysis.service.AnalysisPdfModel;
import com.baian.blockchainanalysis.utils.SnowflakeIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.util.UriUtils;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* @program: block-chain-cloud-parent
* @description:
* @author: <发哥讲Java-694204477@qq.com>
* @create: 2023-05-17 15:22
**/
@Slf4j
public class PdfDownCtlUtil {
/**
* 下载文件通用方法
*
* @param outputFilePath
* @param downFileName
* @param request
* @param response
*/
public static void downFile(String outputFilePath, String downFileName, HttpServletRequest request, HttpServletResponse response) {
File file = new File(outputFilePath);
// 下载文件
// 设置响应的内容类型,让浏览器知道下载的是一个文件
ServletContext context = request.getServletContext();
// get MIME type of the file
String mimeType = context.getMimeType(outputFilePath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
log.info("context getMimeType is null");
}
log.info("MIME type: " + mimeType);
// 设置响应头信息,告诉浏览器文件的名称和长度
// set content attributes for the response
response.setContentType(mimeType);
response.setCharacterEncoding("utf-8");
response.setContentLength((int) file.length());
String headerValue = String.format("attachment; filename=%s",
UriUtils.encode(downFileName, StandardCharsets.UTF_8));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);
// Copy the stream to the response's output stream.
try {
InputStream myStream = new FileInputStream(outputFilePath);
IOUtils.copy(myStream, response.getOutputStream());
response.flushBuffer();
} catch (IOException e) {
e.printStackTrace();
}
}
}