提示:本文仅记录本人工作中遇到的难点与个人见解,仅供参考,如有问题请见谅。
目录
前言
一、创建UploadUtil工具类
二、需要在yml中定义上传到系统的路径
三、创建UploadControlle
前言
文件上传,也称为upload,是指将本地图片、视频、音频等文件上传到服务器上,以供用户预览或下载。
一、创建UploadUtil工具类
代码如下:
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.CommonUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;import java.io.File;/*** 该类处理文件的上传(图片、PDF、视频)*/
@Slf4j
public class UploadUtil {/*** Web端上传文件工具类:返回图片、文件、视频的保存路径* @param multipartFile 文件* @param path 保存路径(图片、电子书、视频的保存路径是不一致的)* @param kind 上传文件的种类;图片填"images",pdf填"pdf",视频填"video"*/public static String upload(MultipartFile multipartFile, String path, String kind) {try {// 先创建文件夹,例如 E://upload//images或者/opt/yhs/imagesFile file = new File(path + File.separator);if (!file.exists()) {file.mkdirs();}// 文件原始名(包括后缀);例如123456.txtString orgName = multipartFile.getOriginalFilename();// 不包括后缀的文件名;例如123456String preName = orgName.substring(0, orgName.lastIndexOf("."));// 如果文件名太长,则只截取文件名前15位字符+后缀,再拼接时间戳进行返回并保存if (preName.length() > 15) {orgName = preName.substring(0, 15) + orgName.substring(orgName.lastIndexOf("."));}// 判断文件名是否带盘符并重新处理orgName = CommonUtils.getFileName(orgName);// 生成的新文件名String fileName;if (orgName.contains(".")) {// 示例:test.123456.png,经过处理后得到:test.123456_1661136943533.pngfileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));} else {// 文件名中没有"."说明这不是一个正常的文件return "";}// 将用户上传的文件复制到指定目录String savePath = file.getPath() + File.separator + fileName;File saveFile = new File(savePath);FileCopyUtils.copy(multipartFile.getBytes(), saveFile);// 返回给前端的具体完整地址String dbPath = "";// 获取系统类型(Win和Linux返回的路径是不一样的)String osName = System.getProperty("os.name");if (osName.startsWith("Windows")) {// 这是windows系统上的保存路径switch (kind) {case "images":dbPath = "/upload/images" + File.separator + fileName;break;case "pdf":dbPath = "/upload/pdf" + File.separator + fileName;break;default:dbPath = "/upload/video" + File.separator + fileName;}} else if (osName.startsWith("Linux")) {// 这是linux系统上的保存路径dbPath = file.getPath() + File.separator + fileName;}if (dbPath.contains("\\")) {dbPath = dbPath.replace("\\", "/");}// 返回完整目录+文件名,例如/upload/images/aaa.png或者/opt/yhs/images/aaa.png;前端根据项目具体地址拼接即可return dbPath;} catch (Exception e) {log.error(e.getMessage(), e);}return "";}
}
二、需要在yml中定义上传到系统的路径
# 图片保存路径(不管什么图片,全都保存在该目录)
images: E://upload//images
# pdf保存路径
pdf: E://upload//pdf
# 视频保存路径(不管什么视频,全部保存在该目录)
video: E://upload//video
三、创建UploadController
代码如下:
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.util.UploadUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;@Slf4j
@Api(tags = "文件上传和下载")
@RestController
@RequestMapping("/upload")
public class UploadController {@Value(value = "${jeecg.path.video}")private String videoPath;@Value(value = "${jeecg.path.images}")private String imagesPath;@Value(value = "${jeecg.path.pdf}")private String pdfPath;/*** 图片上传*/@ApiOperation(value = "上传图片接口", notes = "上传图片接口")@RequestMapping(value = "/uploadImage", method = RequestMethod.POST)public Result<String> uploadImage(MultipartFile file) {Result<String> result = new Result<>();// 图片保存到本地String savePath = UploadUtil.upload(file, imagesPath, "images");if (oConvertUtils.isNotEmpty(savePath)) {result.setResult(savePath);result.setSuccess(true);} else {result.setMessage("上传失败,请稍后再试!");result.setSuccess(false);}return result;}/*** 视频上传(一次上传单个视频)*/@ApiOperation(value = "上传视频接口", notes = "上传视频接口")@RequestMapping(value = "/uploadVideo", method = RequestMethod.POST)public Result<String> uploadVideo(MultipartFile file) {Result<String> result = new Result<>();// 视频保存到本地String savePath = UploadUtil.upload(file, videoPath, "video");if (oConvertUtils.isNotEmpty(savePath)) {result.setResult(savePath);result.setSuccess(true);} else {result.setMessage("上传失败,请稍后再试!");result.setSuccess(false);}return result;}/*** pdf或视频下载统一接口* @param path 文件保存路径* @param response 文件流*/@ApiOperation(value = "下载文件(视频或pdf)", notes = "下载文件")@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)public Result<String> download(@RequestParam(name = "path") String path, HttpServletResponse response) {Result<String> result = new Result<>();if (oConvertUtils.isEmpty(path) || path.equals("null")) {result.setMessage("下载失败,未找到对应文件!");result.setSuccess(false);return result;}InputStream inputStream = null;OutputStream outputStream = null;// 获取文件名String fileName = path.substring(path.lastIndexOf("/") + 1);// 拼接出文件的完整路径String string = bookPath + File.separator + fileName;try {string = string.replace("..", "");if (string.endsWith(",")) {string = string.substring(0, string.length() - 1);}File file = new File(string);if (!file.exists()) {result.setMessage("下载失败,文件不存在!");result.setSuccess(false);return result;}// 设置强制下载不打开(下面这行代码会导致异常,所以暂时注释)// response.setContentType("application/force-download");// 设置content-disposition响应头控制浏览器以下载的形式打开文件response.addHeader("Content-Disposition", "attachment; fileName=" + URLEncoder.encode(fileName, "UTF-8"));// 获取要下载的文件输入流inputStream = new BufferedInputStream(new FileInputStream(file));// 通过response对象获取OutputStream流outputStream = response.getOutputStream();// 获取文件长度,前端就可得到下载进度response.setContentLength((int) file.length());int length;// 创建数据缓冲区byte[] buf = new byte[1024];while ((length = inputStream.read(buf)) != -1) {outputStream.write(buf, 0, length);}response.flushBuffer();result.setMessage("下载成功!");result.setSuccess(true);} catch (Exception e) {log.error(e.getMessage(), e);result.setMessage("下载失败!");result.setSuccess(false);} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}}return result;}}