步骤一:书写配置文件
package com.rjrz.backend.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfig implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("file:/var/uploads/");
}
}
步骤二:在Linux服务器中创建文件,并给予文件书写权限
sudo mkdir -p /var/uploads
sudo chmod -R 777 /var/uploads
步骤三:在MySQL中创建表
sql代码如下:
CREATE TABLE `file_sheet` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '文件id',
`file_name` varchar(1024) DEFAULT NULL COMMENT '文件名称',
`file_path` varchar(1024) DEFAULT NULL COMMENT '文件地址',
`upload_path` date DEFAULT NULL COMMENT '文件上传日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
步骤四: 书写代码
Dao层代码:
package com.rjrz.backend.dao;
import com.rjrz.backend.model.FileMapping;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface FileUploadDao {
@Insert("INSERT INTO " +
"file_sheet (file_name,file_path,upload_path) " +
"VALUES " +
"(#{fileName},#{filePath},#{uploadTime})")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
void uploadFile(FileMapping mapping);
// 根据文件路径删除数据库中的记录
@Delete("DELETE FROM file_sheet WHERE file_path = #{filePath}")
void deleteFileByFilePath(@Param("filePath") String filePath);
}
Service 层代码:
package com.rjrz.backend.service;
import com.rjrz.backend.dao.FileUploadDao;
import com.rjrz.backend.model.FileMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@Transactional
public class FileUploadService {
@Autowired
FileUploadDao fileUploadDao;
public enum DirType {
FILE,IMG
}
private static String getServerIP = "http://127.0.0.1:8088";
private static String getUploadDir(DirType type) {
// 获取当前工作目录
String userDir = "/var/uploads";
// 获取当前日期并格式化为"yyyy/MM"
LocalDate now = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM");
switch (type) {
case FILE:
return userDir + "/uploads/" + now.format(formatter) + "/";
case IMG:
return userDir + "/img/" + now.format(formatter) + "/";
default:
return userDir + "/default/" + now.format(formatter) + "/";
}
}
public FileMapping uploadFile(MultipartFile file) throws IOException {
if (file.isEmpty()) return null;
// 根据当前年月生成上传目录
String uploadDir = getUploadDir(DirType.FILE);
Path uploadPath = Paths.get(uploadDir);
// 如果目录不存在,则创建新目录
if (!Files.exists(uploadPath)) Files.createDirectories(uploadPath);
// 将文件保存到服务器上的指定位置
byte[] bytes = file.getBytes();
String[] split = file.getOriginalFilename().split("\\.");
if (split.length != 2) return null;
String fileName = split[0] + new Date().getTime() + "." + split[1];
Path path = Paths.get(uploadDir + fileName);
Files.write(path, bytes);
//储存映射到数据库
FileMapping mapping = new FileMapping(){{
setFileName(file.getOriginalFilename());
setFilePath(uploadDir + fileName);
setUploadTime(LocalDateTime.now());
}};
fileUploadDao.uploadFile(mapping);
return mapping;
}
public Boolean deleteFileByMonth(String time, DirType type) throws IOException {
// 构建要删除的文件目录路径
String dirPath = "/var/uploads" + "/uploads/" + time + "/";
switch (type) {
case FILE:
dirPath += "/uploads/";
break;
case IMG:
dirPath += "/img/";
break;
default:
dirPath += "/default/";
}
dirPath += time + "/";
Path dir = Paths.get(dirPath);
if (!Files.exists(dir)) {
// 如果指定的月份目录不存在,则直接返回false
return false;
}
List<Path> filesToDelete = new ArrayList<>();
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
filesToDelete.add(file);
return FileVisitResult.CONTINUE;
}
});
// 删除每个文件及其在数据库中的记录
for (Path file : filesToDelete) {
// 删除物理文件
Files.delete(file);
// 假设数据库中的文件路径是唯一的,可以据此删除记录
String filePath = file.toString();
fileUploadDao.deleteFileByFilePath(filePath);
}
// 删除空目录
Files.delete(dir);
return true;
}
public FileMapping uploadImg(MultipartFile file) throws IOException {
if (file.isEmpty()) return null;
//检查文件是否为图片格式
String contentType = file.getContentType();
if (contentType == null || !contentType.startsWith("image/")) return null;
// 根据当前年月生成上传目录
String uploadDir = getUploadDir(DirType.IMG);
Path uploadPath = Paths.get(uploadDir);
// 如果目录不存在,则创建新目录
if (!Files.exists(uploadPath)) Files.createDirectories(uploadPath);
// 将文件保存到服务器上的指定位置
byte[] bytes = file.getBytes();
String originalFilename = file.getOriginalFilename();
String[] split = originalFilename.split("\\.");
if (split.length != 2) return null;
String fileName = split[0] + new java.util.Date().getTime() + "." + split[1];
Path path = Paths.get(uploadDir + fileName);
Files.write(path, bytes);
// 储存映射到数据库
FileMapping mapping = new FileMapping(){{
setFileName(originalFilename);
setFilePath(uploadDir + fileName);
setUploadTime(LocalDateTime.now());
}};
fileUploadDao.uploadFile(mapping);
//切换本机地址改为网络地址
String localPath = mapping.getFilePath();
String webPath = localPath.replace("/var/uploads", getServerIP + "/static");
mapping.setFilePath(webPath);
return mapping;
}
}
Web层代码:
package com.rjrz.backend.web;
import com.rjrz.backend.model.FileMapping;
import com.rjrz.backend.model.Result;
import com.rjrz.backend.service.FileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.Objects;
@RestController
@RequestMapping(value = "/api/upload")
public class FileUploadCtl {
@Autowired
FileUploadService fileUploadService;
@RequestMapping(path = "/uploadFile" , method = RequestMethod.POST)
public Result uploadFile(@RequestParam("file")MultipartFile file){
try {
FileMapping fileMapping = fileUploadService.uploadFile(file);
if (!Objects.isNull(fileMapping)) {
return new Result(200,"上传成功",fileMapping);
} else {
return new Result(400,"上传失败",null);
}
} catch (Exception e) {
return new Result(500,"服务器错误,请稍后重试",null);
}
}
@RequestMapping(path = "/deleteFileByMonth" , method = RequestMethod.GET)
public Result deleteFileByMonth(String time) {
try {
Boolean bool = fileUploadService.deleteFileByMonth(time, FileUploadService.DirType.FILE);
if (bool) {
return new Result(200,"删除成功",null);
} else {
return new Result(400,"删除失败", null);
}
} catch (Exception e) {
e.printStackTrace();
return new Result(500,"服务器错误,请稍后重试",null);
}
}
@RequestMapping(path = "/uploadImg", method = RequestMethod.POST)
public Result uploadImg(@RequestParam("file")MultipartFile file){
try {
FileMapping fileMapping = fileUploadService.uploadImg(file);
if (!Objects.isNull(fileMapping)) {
return new Result(200,"上传成功",fileMapping);
} else {
return new Result(400,"上传失败",null);
}
} catch (Exception e) {
return new Result(500,"服务器错误,请稍后重试",null);
}
}
}
步骤五:部署Java项目
1.用idea打包成jar文件
2.书写Dokcerfile配置文件
FROM openjdk:8-jdk-alpine
ADD /rjrz-0.1.21.jar rjrz-0.1.21.jar
EXPOSE 8088
CMD ["java", "-jar", "rjrz-0.1.21.jar"]
这里注意:项目jar包文件名称要对应,并且要在同一层级
3.打包成本地镜像并部署(这里默认你已经安装docker)
//打包成镜像
docker build -t file-upload .
//运行镜像
docker run -d -p 8088:8088 \
--name file-upload \
--restart=always \
-v /var/uploads \
file-upload
结果
图片素材来源于网络,星极天下第一