文件上传

This commit is contained in:
mashuai 2025-03-08 10:32:21 +08:00
parent 40b6fa35b9
commit 75332ddd6a
4 changed files with 223 additions and 63 deletions

View File

@ -1,16 +1,18 @@
package com.bonus.sgzb.system.controller; package com.bonus.sgzb.system.controller;
import com.bonus.sgzb.common.core.utils.StringHelper; import cn.hutool.core.util.ObjectUtil;
import com.bonus.sgzb.common.core.web.domain.AjaxResult; import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.system.domain.FileInfo; import com.bonus.sgzb.system.domain.FileInfo;
import com.bonus.sgzb.system.service.SysFileService; import com.bonus.sgzb.system.service.SysFileService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
@ -25,6 +27,7 @@ import java.nio.charset.StandardCharsets;
*/ */
@RestController @RestController
@RequestMapping("/sys/file") @RequestMapping("/sys/file")
@Slf4j
public class SysFileController { public class SysFileController {
@Resource @Resource
@ -36,23 +39,19 @@ public class SysFileController {
@PostMapping("/upload") @PostMapping("/upload")
@ApiOperation(value = "文件上传") @ApiOperation(value = "文件上传")
public AjaxResult upload(HttpServletRequest request) { public AjaxResult upload(MultipartFile file) {
String limitWords = request.getParameter("limitWords"); try
FileInfo file = new FileInfo(); {
try { // 上传并返回访问地址
file = service.uploadFile(request); if (ObjectUtil.isEmpty(file)) { return AjaxResult.error("上传文件不能为空");}
if (limitWords != null && file.getWords() > Integer.parseInt(limitWords)){ FileInfo sysFile = service.uploadFile(file);
return AjaxResult.error("上传文件字数超出限制字数!"); return AjaxResult.success(sysFile);
} }
}catch (Exception e){ catch (Exception e)
{
log.error("上传文件失败", e);
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
if (file != null && file.getId() != 0){
return AjaxResult.success(file);
}else {
return AjaxResult.error("文件上传失败!");
}
} }
@ApiOperation(value = "模板", httpMethod = "GET") @ApiOperation(value = "模板", httpMethod = "GET")

View File

@ -15,11 +15,11 @@ public interface SysFileService
{ {
/** /**
* 文件上传接口 * 文件上传接口
* @param request * @param file
* @return * @return
* @throws Exception * @throws Exception
*/ */
FileInfo uploadFile(HttpServletRequest request) throws Exception; FileInfo uploadFile(MultipartFile file) throws Exception;
/** /**
* 上传头像 * 上传头像

View File

@ -1,15 +1,14 @@
package com.bonus.sgzb.system.service.impl; package com.bonus.sgzb.system.service.impl;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.bonus.sgzb.common.core.constant.HttpStatus;
import com.bonus.sgzb.common.core.utils.DateTimeHelper; import com.bonus.sgzb.common.core.utils.DateTimeHelper;
import com.bonus.sgzb.common.core.utils.GlobalConstants; import com.bonus.sgzb.common.core.utils.GlobalConstants;
import com.bonus.sgzb.common.core.web.domain.AjaxResult;
import com.bonus.sgzb.common.security.utils.SecurityUtils; import com.bonus.sgzb.common.security.utils.SecurityUtils;
import com.bonus.sgzb.system.domain.FileInfo; import com.bonus.sgzb.system.domain.FileInfo;
import com.bonus.sgzb.system.mapper.FileInfoMapper; import com.bonus.sgzb.system.mapper.FileInfoMapper;
import com.bonus.sgzb.system.service.SysFileService; import com.bonus.sgzb.system.service.SysFileService;
import com.bonus.sgzb.system.service.feign.FileClient; import com.bonus.sgzb.system.service.feign.FileClient;
import com.bonus.sgzb.system.util.FileUploadUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hwpf.extractor.WordExtractor; import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.openxml4j.util.ZipSecureFile;
@ -17,7 +16,6 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
@ -45,6 +43,18 @@ public class SysFileServiceImpl implements SysFileService {
@Value("${file.path}") @Value("${file.path}")
private String localFilePath; private String localFilePath;
/**
* 资源映射路径 前缀
*/
@Value("${file.prefix}")
public String localFilePrefix;
/**
* 域名或本机访问地址
*/
@Value("${file.domain}")
public String domain;
// 允许的文件格式 // 允许的文件格式
private static final List<String> ALLOWED_EXTENSIONS = Arrays.asList("jpg", "jpeg", "txt", "png", "pdf", "docx", "doc", "xlsx", "xls"); private static final List<String> ALLOWED_EXTENSIONS = Arrays.asList("jpg", "jpeg", "txt", "png", "pdf", "docx", "doc", "xlsx", "xls");
@ -59,48 +69,13 @@ public class SysFileServiceImpl implements SysFileService {
* @throws Exception * @throws Exception
*/ */
@Override @Override
public FileInfo uploadFile(HttpServletRequest request) throws Exception { public FileInfo uploadFile(MultipartFile file) throws Exception {
FileInfo file = new FileInfo(); String name = FileUploadUtils.upload(localFilePath, file);
StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request; String url = domain + localFilePrefix + name;
String photoType = req.getParameter("fileType"); FileInfo fileInfo = new FileInfo();
Long userId = SecurityUtils.getLoginUser().getUserid(); fileInfo.setFileUrl(url);
HashMap<String, Object> map = getFile(req); fileInfo.setFileName(name);
List<MultipartFile> items = (List<MultipartFile>) map.get("filePath"); return fileInfo;
MultipartFile item = items.get(0);
// 获取文件后缀名
String fileExtension = item.getOriginalFilename().substring(item.getOriginalFilename().lastIndexOf(".") + 1);
if (!ALLOWED_EXTENSIONS.contains(fileExtension.toLowerCase())) {
throw new Exception("不支持该文件格式");
}
// 检查文件大小
long fileSize = item.getSize();
long maxSize = 20 * 1024 * 1024; // 20MB
if (fileSize > maxSize) {
throw new Exception("文件太大,请重新上传");
}
try {
String url = saveFile(request, item, photoType);
//AjaxResult res = fileClient.uploadFile(item);
//String url = (String) res.get("msg");
if (url != null) {
int words = getFileText(item);
String fileName = item.getOriginalFilename();
String type = fileName.substring(fileName.lastIndexOf(".") + 1);
long size = item.getSize() / 1024 / 1024;
file.setFileName(fileName);
file.setFileUrl(url);
file.setCreator(userId.toString());
file.setType(type);
file.setSize(size + "M");
file.setWords(words);
file.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
file.setCreateTime(new Date());
dao.insertFileInfo(file);
}
} catch (Exception e) {
e.printStackTrace();
}
return file;
} }
/** /**

View File

@ -0,0 +1,186 @@
package com.bonus.sgzb.system.util;
import com.bonus.sgzb.common.core.exception.file.FileException;
import com.bonus.sgzb.common.core.exception.file.FileNameLengthLimitExceededException;
import com.bonus.sgzb.common.core.exception.file.FileSizeLimitExceededException;
import com.bonus.sgzb.common.core.exception.file.InvalidExtensionException;
import com.bonus.sgzb.common.core.utils.DateUtils;
import com.bonus.sgzb.common.core.utils.StringUtils;
import com.bonus.sgzb.common.core.utils.file.FileTypeUtils;
import com.bonus.sgzb.common.core.utils.file.MimeTypeUtils;
import com.bonus.sgzb.common.core.utils.uuid.Seq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Objects;
/**
* 文件上传工具类
*
* @author ruoyi
*/
public class FileUploadUtils
{
/**
* 默认大小 50M
*/
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
/**
* 默认的文件名最大长度 100
*/
public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/**
* 根据文件路径上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @return 文件名称
* @throws IOException
*/
public static final String upload(String baseDir, MultipartFile file) throws IOException
{
try
{
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
}
catch (FileException fe)
{
throw new IOException(fe.getDefaultMessage(), fe);
}
catch (Exception e)
{
throw new IOException(e.getMessage(), e);
}
}
/**
* 文件上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @param allowedExtension 上传文件类型
* @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时
* @throws InvalidExtensionException 文件校验异常
*/
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException
{
int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(file, allowedExtension);
String fileName = extractFilename(file);
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
file.transferTo(Paths.get(absPath));
return getPathFileName(fileName);
}
/**
* 编码文件名
*/
public static final String extractFilename(MultipartFile file)
{
return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.UPLOAD_SEQ_TYPE), FileTypeUtils.getExtension(file));
}
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
File desc = new File(uploadDir + File.separator + fileName);
if (!desc.exists())
{
if (!desc.getParentFile().exists())
{
desc.getParentFile().mkdirs();
}
}
return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
}
private static final String getPathFileName(String fileName) throws IOException
{
String pathFileName = "/" + fileName;
return pathFileName;
}
/**
* 文件大小校验
*
* @param file 上传的文件
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws InvalidExtensionException 文件校验异常
*/
public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, InvalidExtensionException
{
long size = file.getSize();
if (size > DEFAULT_MAX_SIZE)
{
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
}
String fileName = file.getOriginalFilename();
String extension = FileTypeUtils.getExtension(file);
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
{
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
{
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
{
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
{
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
fileName);
}
else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
{
throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
fileName);
}
else
{
throw new InvalidExtensionException(allowedExtension, extension, fileName);
}
}
}
/**
* 判断MIME类型是否是允许的MIME类型
*
* @param extension 上传文件类型
* @param allowedExtension 允许上传文件类型
* @return true/false
*/
public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
{
for (String str : allowedExtension)
{
if (str.equalsIgnoreCase(extension))
{
return true;
}
}
return false;
}
}