MultipartFile实现文件上传
这里记录下使用SpringBoot的MultipartFile类实现文件上传功能。
Controller层
@Tag(name = "ResourceController", description = "前台门户-资源模块")
@RestController
@RequestMapping(ApiRouterConsts.API_FRONT_RESOURCE_URL_PREFIX)
@RequiredArgsConstructor
public class ResourceController {private final ResourceService resourceService;/*** 图片上传接口*/@Operation(summary = "图片上传接口")@PostMapping("/image")RestResp<String> uploadImage(@Parameter(description = "上传文件") @RequestParam("file") MultipartFile file) {return resourceService.uploadImage(file);}}
Service层
@Service
@RequiredArgsConstructor
@Slf4j
public class ResourceServiceImpl implements ResourceService {@SneakyThrows@Overridepublic RestResp<String> uploadImage(MultipartFile file) {LocalDateTime now = LocalDateTime.now();String savePath =SystemConfigConsts.IMAGE_UPLOAD_DIRECTORY+ now.format(DateTimeFormatter.ofPattern("yyyy")) + File.separator+ now.format(DateTimeFormatter.ofPattern("MM")) + File.separator+ now.format(DateTimeFormatter.ofPattern("dd"));String oriName = file.getOriginalFilename();assert oriName != null;String saveFileName = IdWorker.get32UUID() + oriName.substring(oriName.lastIndexOf("."));File saveFile = new File(fileUploadPath + savePath, saveFileName);if (!saveFile.getParentFile().exists()) {boolean isSuccess = saveFile.getParentFile().mkdirs();if (!isSuccess) {throw new BusinessException(ErrorCodeEnum.USER_UPLOAD_FILE_ERROR);}}file.transferTo(saveFile);if (Objects.isNull(ImageIO.read(saveFile))) {// 上传的文件不是图片Files.delete(saveFile.toPath());throw new BusinessException(ErrorCodeEnum.USER_UPLOAD_FILE_TYPE_NOT_MATCH);}return RestResp.ok(savePath + File.separator + saveFileName);}
}
@RequiredArgsConstructor
这里顺便提一嘴 @RequiredArgsConstructor注解的使用。
@RequiredArgsConstructor 是 Lombok 提供的注解,它会在编译时自动为类生成一个包含所有 final 修饰的字段和未初始化的 @NonNull 注解修饰字段的构造函数。
@SneakyThrows
@SneakyThrows 是 Lombok 库提供的一个注解,其主要作用是简化异常处理代码,允许方法抛出受检异常(Checked Exception)却无需在方法签名中显式声明。下面详细介绍该注解。
在 Java 里,异常分为受检异常和非受检异常。
受检异常:编译器会强制要求处理的异常,如 IOException、SQLException 等。方法若可能抛出受检异常,就必须在方法签名中使用 throws 关键字声明,或者在方法内部使用 try-catch 块捕获处理。
非受检异常:继承自 RuntimeException 的异常,编译器不会强制要求处理,如 NullPointerException、ArrayIndexOutOfBoundsException 等。