文件base64 上传
This commit is contained in:
parent
9cb6d60b22
commit
b3b96d9937
|
|
@ -3,7 +3,10 @@ package com.bonus.file.controller;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.bonus.common.core.constant.HttpStatus;
|
import com.bonus.common.core.constant.HttpStatus;
|
||||||
import com.bonus.common.core.utils.Base64Utils;
|
import com.bonus.common.core.utils.Base64Utils;
|
||||||
|
import com.bonus.common.core.utils.StringUtils;
|
||||||
import com.bonus.common.core.web.domain.AjaxResult;
|
import com.bonus.common.core.web.domain.AjaxResult;
|
||||||
|
import com.bonus.file.entity.Base64File;
|
||||||
|
import com.bonus.file.entity.Base64ToMultipartFile;
|
||||||
import com.bonus.file.service.ISysFileService;
|
import com.bonus.file.service.ISysFileService;
|
||||||
import com.bonus.system.api.domain.SysFile;
|
import com.bonus.system.api.domain.SysFile;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
|
|
@ -11,16 +14,15 @@ import io.swagger.annotations.ApiOperation;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件请求处理
|
* 文件请求处理
|
||||||
|
|
@ -29,8 +31,7 @@ import java.net.URLDecoder;
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@Api("服务文件存储")
|
@Api("服务文件存储")
|
||||||
public class SysFileController
|
public class SysFileController {
|
||||||
{
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
||||||
|
|
||||||
private final ISysFileService sysFileService;
|
private final ISysFileService sysFileService;
|
||||||
|
|
@ -42,22 +43,91 @@ public class SysFileController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单文件上传
|
* 单文件上传
|
||||||
|
*
|
||||||
* @param file 单个文件
|
* @param file 单个文件
|
||||||
* @return 文件信息,包括文件名和文件路径
|
* @return 文件信息,包括文件名和文件路径
|
||||||
*/
|
*/
|
||||||
@PostMapping("upload")
|
@PostMapping("upload")
|
||||||
@ApiOperation("上传本地文件到服务器")
|
@ApiOperation("上传本地文件到服务器")
|
||||||
public AjaxResult upload(MultipartFile file)
|
public AjaxResult upload(MultipartFile file) {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
// 上传并返回访问地址
|
// 上传并返回访问地址
|
||||||
if (ObjectUtil.isEmpty(file)) { return AjaxResult.error("上传文件不能为空");}
|
if (ObjectUtil.isEmpty(file)) {
|
||||||
|
return AjaxResult.error("上传文件不能为空");
|
||||||
|
}
|
||||||
SysFile sysFile = sysFileService.uploadFile(file);
|
SysFile sysFile = sysFileService.uploadFile(file);
|
||||||
return AjaxResult.success(sysFile);
|
return AjaxResult.success(sysFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("上传文件失败", e);
|
||||||
|
return AjaxResult.error(e.getMessage());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
}
|
||||||
{
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单文件上传(支持Base64格式)
|
||||||
|
*
|
||||||
|
* @param base64File Base64编码的文件内容
|
||||||
|
* @param fileName 文件名(可选)
|
||||||
|
* @param fileType 文件类型(如image/png,可选)
|
||||||
|
* @return 文件信息,包括文件名和文件路径
|
||||||
|
*/
|
||||||
|
@PostMapping("uploadBase64")
|
||||||
|
@ApiOperation("上传Base64文件到服务器")
|
||||||
|
public AjaxResult uploadBase64(@RequestBody Base64File entity) {
|
||||||
|
try {
|
||||||
|
// 验证Base64数据是否为空
|
||||||
|
if (StringUtils.isEmpty(entity.getBase64File())) {
|
||||||
|
return AjaxResult.error("上传文件内容不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理可能包含的data URI前缀(如"data:image/png;base64,")
|
||||||
|
String base64Data;
|
||||||
|
if (entity.getBase64File().startsWith("data:")) {
|
||||||
|
// 提取真正的base64内容
|
||||||
|
String[] parts = entity.getBase64File().split(",");
|
||||||
|
if (parts.length < 2) {
|
||||||
|
return AjaxResult.error("Base64格式不正确");
|
||||||
|
}
|
||||||
|
base64Data = parts[1];
|
||||||
|
|
||||||
|
// 如果没传fileType,尝试从data URI中提取
|
||||||
|
if (entity.getFileType() == null && parts[0].contains(":")) {
|
||||||
|
entity.setFileType(parts[0].split(":")[1].split(";")[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base64Data = entity.getBase64File();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码Base64
|
||||||
|
byte[] fileBytes = Base64.getDecoder().decode(base64Data);
|
||||||
|
|
||||||
|
// 如果没传文件名,生成一个随机文件名
|
||||||
|
if (StringUtils.isEmpty(entity.getFileName())) {
|
||||||
|
entity.setFileName(UUID.randomUUID().toString());
|
||||||
|
// 如果知道文件类型,添加合适的扩展名
|
||||||
|
if (entity.getFileType() != null) {
|
||||||
|
String extension = "";
|
||||||
|
if (entity.getFileType().equals("image/png")) {
|
||||||
|
extension = ".png";
|
||||||
|
} else if (entity.getFileType().equals("image/jpeg")) {
|
||||||
|
extension = ".jpg";
|
||||||
|
} else if (entity.getFileType().equals("application/pdf")) {
|
||||||
|
extension = ".pdf";
|
||||||
|
}
|
||||||
|
entity.setFileName(entity.getFileName() + extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建临时MultipartFile对象
|
||||||
|
MultipartFile multipartFile = new Base64ToMultipartFile(fileBytes, entity.getFileName(), entity.getFileType());
|
||||||
|
// 调用原有的上传逻辑
|
||||||
|
SysFile sysFile = sysFileService.uploadFile(multipartFile);
|
||||||
|
return AjaxResult.success(sysFile);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
log.error("Base64解码失败", e);
|
||||||
|
return AjaxResult.error("Base64格式不正确");
|
||||||
|
} catch (Exception e) {
|
||||||
log.error("上传文件失败", e);
|
log.error("上传文件失败", e);
|
||||||
return AjaxResult.error(e.getMessage());
|
return AjaxResult.error(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
@ -65,30 +135,33 @@ public class SysFileController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多文件上传
|
* 多文件上传
|
||||||
|
*
|
||||||
* @param files 多个文件流
|
* @param files 多个文件流
|
||||||
* @return 文件信息
|
* @return 文件信息
|
||||||
*/
|
*/
|
||||||
@PostMapping("/uploadFiles")
|
@PostMapping("/uploadFiles")
|
||||||
public AjaxResult uploadFile(MultipartFile[] files) {
|
public AjaxResult uploadFile(MultipartFile[] files) {
|
||||||
try {
|
try {
|
||||||
if (ObjectUtil.isEmpty(files)) { return AjaxResult.error("上传文件不能为空");}
|
if (ObjectUtil.isEmpty(files)) {
|
||||||
|
return AjaxResult.error("上传文件不能为空");
|
||||||
|
}
|
||||||
return AjaxResult.success(sysFileService.uploadFiles(files));
|
return AjaxResult.success(sysFileService.uploadFiles(files));
|
||||||
} catch (Exception e)
|
} catch (Exception e) {
|
||||||
{
|
|
||||||
return AjaxResult.error(e.getMessage());
|
return AjaxResult.error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件下载
|
* 文件下载
|
||||||
* @param response 请求响应
|
*
|
||||||
|
* @param response 请求响应
|
||||||
* @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
* @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
||||||
*/
|
*/
|
||||||
@GetMapping("/download")
|
@GetMapping("/download")
|
||||||
public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws IOException {
|
public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws IOException {
|
||||||
try {
|
try {
|
||||||
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
||||||
sysFileService.downloadFile(response, fileUrl);
|
sysFileService.downloadFile(response, fileUrl);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("downloadFile error:{}", e.getMessage());
|
log.error("downloadFile error:{}", e.getMessage());
|
||||||
response.setStatus(HttpStatus.ERROR);
|
response.setStatus(HttpStatus.ERROR);
|
||||||
|
|
@ -105,10 +178,11 @@ public class SysFileController
|
||||||
/**
|
/**
|
||||||
* 文件删除
|
* 文件删除
|
||||||
* 从各个存储平台删除文件
|
* 从各个存储平台删除文件
|
||||||
|
*
|
||||||
* @param objectKey * @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
* @param objectKey * @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
||||||
*/
|
*/
|
||||||
@PostMapping("/deleteFile")
|
@PostMapping("/deleteFile")
|
||||||
public AjaxResult deleteFile(@RequestParam("objectKey") String objectKey) {
|
public AjaxResult deleteFile(@RequestParam("objectKey") String objectKey) {
|
||||||
try {
|
try {
|
||||||
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
||||||
sysFileService.deleteFile(fileUrl);
|
sysFileService.deleteFile(fileUrl);
|
||||||
|
|
@ -120,37 +194,38 @@ public class SysFileController
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 单文件上传到指定文件夹
|
* 单文件上传到指定文件夹
|
||||||
|
*
|
||||||
* @param file 单个文件
|
* @param file 单个文件
|
||||||
* @return 文件信息,包括文件名和文件路径
|
* @return 文件信息,包括文件名和文件路径
|
||||||
*/
|
*/
|
||||||
@PostMapping("uploadToFolder")
|
@PostMapping("uploadToFolder")
|
||||||
@ApiOperation("上传本地文件到服务器")
|
@ApiOperation("上传本地文件到服务器")
|
||||||
public AjaxResult upload(MultipartFile file, String folderName)
|
public AjaxResult upload(MultipartFile file, String folderName) {
|
||||||
{
|
|
||||||
return AjaxResult.success("单文件上传成功");
|
return AjaxResult.success("单文件上传成功");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建文件夹
|
* 创建文件夹
|
||||||
|
*
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
||||||
* @return 文件夹网络路径
|
* @return 文件夹网络路径
|
||||||
*/
|
*/
|
||||||
@PostMapping("/createFolder")
|
@PostMapping("/createFolder")
|
||||||
@ApiOperation("创建文件夹")
|
@ApiOperation("创建文件夹")
|
||||||
public AjaxResult createFolder(@RequestParam("folderName") String folderPath)
|
public AjaxResult createFolder(@RequestParam("folderName") String folderPath) {
|
||||||
{
|
|
||||||
sysFileService.createFolder(folderPath);
|
sysFileService.createFolder(folderPath);
|
||||||
return AjaxResult.success("创建文件夹");
|
return AjaxResult.success("创建文件夹");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list 指定目录下所有文件信息(文件名,文件大小,上传时间,是否目录),包括子文件夹
|
* list 指定目录下所有文件信息(文件名,文件大小,上传时间,是否目录),包括子文件夹
|
||||||
|
*
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
||||||
* @return 文件夹网络路径
|
* @return 文件夹网络路径
|
||||||
*/
|
*/
|
||||||
@GetMapping("/listFiles")
|
@GetMapping("/listFiles")
|
||||||
public AjaxResult listFiles(@RequestParam("folderName") String folderPath) {
|
public AjaxResult listFiles(@RequestParam("folderName") String folderPath) {
|
||||||
return AjaxResult.success(sysFileService.getFilesAndSubfolders(folderPath));
|
return AjaxResult.success(sysFileService.getFilesAndSubfolders(folderPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,13 +233,27 @@ public class SysFileController
|
||||||
/**
|
/**
|
||||||
* 文件夹删除
|
* 文件夹删除
|
||||||
* 从各个存储平台删除文件
|
* 从各个存储平台删除文件
|
||||||
|
*
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
||||||
* @return 文件夹网络路径
|
* @return 文件夹网络路径
|
||||||
*/
|
*/
|
||||||
@PostMapping("/deleteFolder")
|
@PostMapping("/deleteFolder")
|
||||||
public AjaxResult deleteFolder(@RequestParam("folderName") String folderPath) {
|
public AjaxResult deleteFolder(@RequestParam("folderName") String folderPath) {
|
||||||
sysFileService.deleteFolder(folderPath);
|
sysFileService.deleteFolder(folderPath);
|
||||||
return AjaxResult.success("文件夹删除成功");
|
return AjaxResult.success("文件夹删除成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/uploadResume")
|
||||||
|
public AjaxResult uploadResume(@RequestParam("md5") String md5, @RequestParam("chunkIndex") Integer chunkIndex, @RequestParam("file") MultipartFile file, @RequestParam("totalChunks") Integer totalChunks, @RequestParam("filename") String filename) {
|
||||||
|
try {
|
||||||
|
if (ObjectUtil.isEmpty(file)) {
|
||||||
|
return AjaxResult.error("上传文件不能为空");
|
||||||
|
}
|
||||||
|
return AjaxResult.success(sysFileService.uploadResume(md5, chunkIndex, file, totalChunks, filename));
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AjaxResult.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.bonus.file.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Base64File {
|
||||||
|
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
private String base64File;
|
||||||
|
|
||||||
|
private String fileType;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
package com.bonus.file.entity;
|
||||||
|
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义MultipartFile实现,用于包装Base64解码后的数据
|
||||||
|
*/
|
||||||
|
public class Base64ToMultipartFile implements MultipartFile {
|
||||||
|
private final byte[] content;
|
||||||
|
private final String name;
|
||||||
|
private final String contentType;
|
||||||
|
|
||||||
|
public Base64ToMultipartFile(byte[] content, String name, String contentType) {
|
||||||
|
this.content = content;
|
||||||
|
this.name = name;
|
||||||
|
this.contentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOriginalFilename() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return content == null || content.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getSize() {
|
||||||
|
return content.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getBytes() throws IOException {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new ByteArrayInputStream(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transferTo(File dest) throws IOException, IllegalStateException {
|
||||||
|
try (FileOutputStream fos = new FileOutputStream(dest)) {
|
||||||
|
fos.write(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue