用springboot实现通用的文件上传下载功能,并且可以通过postman测试文件上传功能,用浏览器直接调用文件下载功能。
一. 文件上传
1. 代码实现
1)添加 application.properties 配置
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=0
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB
//设置最大上传文件大小
2)新建 FileInfo 类
package com.example.demo.bean;
public class FileInfo {
//文件名
private String fileName;
//文件路径
private String filePath;
//文件大小
private String fileSize;
//文件类型
private String fileType;
//保存信息
private String saveInfo;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public String getSaveInfo() {
return saveInfo;
}
public void setSaveInfo(String saveInfo) {
this.saveInfo = saveInfo;
}
@Override
public String toString() {
return "FileInfo{" +
"fileName='" + fileName + '\'' +
", filePath='" + filePath + '\'' +
", fileSize='" + fileSize + '\'' +
", fileType='" + fileType + '\'' +
", saveInfo='" + saveInfo + '\'' +
'}';
}
}
3)新建 FileController 类
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.bean.FileInfo;
import com.example.demo.service.FileService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
@RestController
@RequestMapping("/file")
@CrossOrigin(value = "*", maxAge = 3600)
public class FileController {
@Resource
private FileService service;
/**文件上传*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public JSONObject uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("savePath") String url) {
JSONObject output = new JSONObject();
FileInfo result = service.uploadFile(file, url);
if (result.getSaveInfo() != null) {
output.put("msg", "failed");
output.put("data", result.getSaveInfo());
} else {
output.put("msg", "succeed");
output.put("data", result);
}
return output;
}
}
4)新建 FileService 类
package com.example.demo.service;
import com.example.demo.bean.FileInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@Service
public class FileService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
public FileInfo uploadFile(MultipartFile file, String url) {
FileInfo fileInfo = new FileInfo();
// 在 uploadPath 文件夹中通过日期对上传的文件归类保存
// 比如:/2019/06/06/cf13891e-4b95-4000-81eb-b6d70ae44930.png
String format = sdf.format(new Date());
File folder = new File(url + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
// 对上传的文件重命名,避免文件重名
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString()
+ oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
// 文件保存
file.transferTo(new File(folder, newName));
// 返回上传文件的访问路径
String filePath = folder.getPath()+newName;
// 返回上传文件详细信息
fileInfo.setFileName(newName);
fileInfo.setFilePath(filePath);
fileInfo.setFileSize(setSize(file.getSize()));
fileInfo.setFileType(file.getContentType());
return fileInfo;
} catch (IOException e) {
fileInfo.setSaveInfo(e.toString());
return fileInfo;
}
}
//将文件大小调整至合适单位
public String setSize(Long size) {
//获取到的size为:1705230
int GB = 1024 * 1024 * 1024;//定义GB的计算常量
int MB = 1024 * 1024;//定义MB的计算常量
int KB = 1024;//定义KB的计算常量
DecimalFormat df = new DecimalFormat("0.00");//格式化小数
String resultSize = "";
if (size / GB >= 1) {
//如果当前Byte的值大于等于1GB
resultSize = df.format(size / (float) GB) + "GB ";
} else if (size / MB >= 1) {
//如果当前Byte的值大于等于1MB
resultSize = df.format(size / (float) MB) + "MB ";
} else if (size / KB >= 1) {
//如果当前Byte的值大于等于1KB
resultSize = df.format(size / (float) KB) + "KB ";
} else {
resultSize = size + "B ";
}
return resultSize;
}
}
2. 使用 postman 测试
如图所示进行设置,点击send按钮成功上传
返回上传成功信息
上传成功
二. 文件下载
1. 代码实现
下载功能代码均续写在以上上传功能代码后
1)添加 application.properties 配置
file.path=D:/work/fileTest
//设置下载文件存放路径
2)续写 FileController 类
package com.example.demo.controller;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.bean.FileInfo;
import com.example.demo.service.FileService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/file")
@CrossOrigin(value = "*", maxAge = 3600)
public class FileController {
@Resource
private FileService service;
@Value("${file.path}")
private String path;
/**文件上传*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public JSONObject uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("savePath") String url) {
JSONObject output = new JSONObject();
FileInfo result = service.uploadFile(file, url);
if (result.getSaveInfo() != null) {
output.put("msg", "failed");
output.put("data", result.getSaveInfo());
} else {
output.put("msg", "succeed");
output.put("data", result);
}
return output;
}
/**下载接口*/
@RequestMapping(value = "/download/{name}", method = RequestMethod.GET)
public JSONObject fileDownload(@PathVariable String name, HttpServletResponse response) throws Exception {
JSONObject output = new JSONObject();
String result = service.fileDownload(path, name, response);
output.put("msg", result);
return output;
}
}
3)续写FileService 类
package com.example.demo.service;
import com.example.demo.bean.FileInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
@Service
public class FileService {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
public FileInfo uploadFile(MultipartFile file, String url) {
FileInfo fileInfo = new FileInfo();
// 在 uploadPath 文件夹中通过日期对上传的文件归类保存
// 比如:/2019/06/06/cf13891e-4b95-4000-81eb-b6d70ae44930.png
String format = sdf.format(new Date());
File folder = new File(url + format);
if (!folder.isDirectory()) {
folder.mkdirs();
}
// 对上传的文件重命名,避免文件重名
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString()
+ oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
// 文件保存
file.transferTo(new File(folder, newName));
// 返回上传文件的访问路径
String filePath = folder.getPath()+newName;
fileInfo.setFileName(newName);
fileInfo.setFilePath(filePath);
fileInfo.setFileSize(setSize(file.getSize()));
fileInfo.setFileType(file.getContentType());
return fileInfo;
} catch (IOException e) {
fileInfo.setSaveInfo(e.toString());
return fileInfo;
}
}
//将文件大小调整至合适单位
public String setSize(Long size) {
//获取到的size为:1705230
int GB = 1024 * 1024 * 1024;//定义GB的计算常量
int MB = 1024 * 1024;//定义MB的计算常量
int KB = 1024;//定义KB的计算常量
DecimalFormat df = new DecimalFormat("0.00");//格式化小数
String resultSize = "";
if (size / GB >= 1) {
//如果当前Byte的值大于等于1GB
resultSize = df.format(size / (float) GB) + "GB ";
} else if (size / MB >= 1) {
//如果当前Byte的值大于等于1MB
resultSize = df.format(size / (float) MB) + "MB ";
} else if (size / KB >= 1) {
//如果当前Byte的值大于等于1KB
resultSize = df.format(size / (float) KB) + "KB ";
} else {
resultSize = size + "B ";
}
return resultSize;
}
//文件下载
public String fileDownload(String path, String name, HttpServletResponse response) throws Exception {
File file = new File(path + File.separator + name);
if (!file.exists()) {
return (name + "文件不存在");
}
response.setContentType("application/force-download");
//通过设置头信息给文件命名,也即是,在前端,文件流被接受完还原成原文件的时候会以你传递的文件名来命名
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", URLEncoder.encode(file.getName(), "utf-8")));
byte[] buffer = new byte[1024];
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream 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 "succeed";
}
}
2. 在浏览器测试下载功能
直接输入地址+文件名
回车成功创建下载任务
文件不存在则返回提示