前言
在一些情境下,用户通过浏览器上传word、excel、pdf等各种类型的文件到系统,上传后可以随时下载。下载文件可以通过虚拟路径的方式访问虚拟路径通过浏览器下载;也可以后端直接发送文件流给前端完成下载,发送文件到网页并从网页下载文件。
上传文件
控制层接口
java
@RequestMapping(value = "/action/upload/new/file/release", method = RequestMethod.POST)
public EiInfo uploadNewActionFileRelease(MultipartFile[] files) {
EiInfo eiInfo = new EiInfo();
ResultMessage resultMessage = service.uploadFile(files[0]);
return ReturnOutInfo.outInfoSuccess(eiInfo, "上传文件成功");
}
服务层处理
java
// 文件保存路径写在了yml文件中
@Value("${file.path.local}")
private String fileLocalPath;
@Override
public ResultMessage uploadFile(MultipartFile file) {
try {
// 封装文件信息
FileSaveDTO fileSaveDTO = FileUtil.handleFileSave(fileLocalPath, file);
return new ResultMessage(1, "文件上传成功");
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(-1, e.getMessage());
}
}
application.yml配置文件保存路径
yml
file:
path:
local:
D:/JavaCode/bao_safety_management_system/bao_safety_platform_system/safe_file/
# img/
tomcat:
http://192.168.0.58:8189/safety-platform/safe/file/
文件工具类 FileUtil
工具类中有保存文件和下载文件两个方法。
java
public class FileUtil {
private static SimpleDateFormat sfFile = new SimpleDateFormat("yyyyMMddHHmmss");
public static FileSaveDTO handleFileSave(String localPath, MultipartFile file) throws Exception {
// 处理传来的文件
String name = file.getOriginalFilename();
String saveName = "file-" + sfFile.format(new Date()) + UUID.randomUUID().toString().substring(0, 4) + name.substring(name.lastIndexOf("."));
File saveFile = new File(localPath + saveName);
file.transferTo(saveFile);
// 判断文件是否是图片类型
// Path path = saveFile.toPath();
// String type = Files.probeContentType(path);
if (Files.probeContentType(saveFile.toPath()) != null) {
return new FileSaveDTO(name, saveName, Files.probeContentType(saveFile.toPath()).startsWith("image/"));
} else {
return new FileSaveDTO(name, saveName, false);
}
}
public static boolean downloadFile(File file, String fileName, HttpServletResponse response) throws Exception {
// 清空缓冲区,状态码和响应头(headers)
response.reset();
// 设置ContentType,响应内容为二进制数据流,编码为utf-8,此处设定的编码是文件内容的编码
response.setContentType("application/octet-stream;charset=utf-8");
// 以(Content-Disposition: attachment; filename="filename.jpg")格式设定默认文件名,设定utf编码,此处的编码是文件名的编码,使能正确显示中文文件名
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "utf-8"));
// 实现文件下载
byte[] buffer = new byte[1024 * 1024 * 1024];
FileInputStream fis = null;
BufferedInputStream bis = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
// 获取字节流
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != -1) {
os.write(buffer, 0, i);
i = bis.read(buffer);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件信息
文件保存在本地后,将文件信息封装到一个对象中返回给调用保存文件功能的方法中,方便下一步操作
java
public class FileSaveDTO {
private String actualName = "";/*文件名字*/
private String saveName = "";/*保存在本地时文件名*/
private Boolean isImage = false;/*是否是图片文件*/
public FileSaveDTO() {
}
public FileSaveDTO(String actualName, String saveName, Boolean isImage) {
this.actualName = actualName;
this.saveName = saveName;
this.isImage = isImage;
}
public String getActualName() {
return actualName;
}
public void setActualName(String actualName) {
this.actualName = actualName;
}
public String getSaveName() {
return saveName;
}
public void setSaveName(String saveName) {
this.saveName = saveName;
}
public Boolean getImage() {
return isImage;
}
public void setImage(Boolean image) {
isImage = image;
}
}
浏览器中使用虚拟路径下载文件
通过如下配置,前端在浏览器中可以通过虚拟路径直接下载文件
http://192.168.0.58:8189/safety-platform/safe/file/xxx.docx
java
@Configuration
public class WebFileConfig implements WebMvcConfigurer {
@Value("${file.path.local}")
private String fileLocalPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/safe/file/**").addResourceLocations("file:" + fileLocalPath);
}
}