SpringBoot实现自定义注解用于文件验证的详细过程(大小、扩展名、MIME类型)

 更新时间:2024年08月25日 09:10:51   作者:码到三十五  
SpringBoot,Spring Cloud中经常需要处理文件上传的功能,为了确保上传的文件满足特定的要求(如扩展名、MIME类型和文件大小),我们可以创建一个自定义注解来简化验证过程,需要的朋友可以参考下

1. 自定义文件验证注解

首先在Spring Boot中定义一个注解,用于标记需要校验的文件字段。这个注解包含验证所需的参数:允许的扩展名、MIME类型和最大文件大小。

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Constraint(validatedBy = FileValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidFile {
    String message() default "{constraints.ValidFileMimeType.message}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    String[] extensions() default {};
    String[] mimeTypes() default {};
    long maxSize() default 1024 * 1024; // 默认最大1MB
}

注释的组成部分:
maxSize: 文件大小限制,默认1M
mimeTypes:MIME类型
extensions:允许的扩展名
message():验证失败时的默认错误消息
constraint(validatedBy = FileValidator.class):自定义的约束器实现

2. 实现约束验证器

接下来,创建一个类来实现ConstraintValidator接口,具体实现文件的扩展名、类型、大小的校验逻辑。

import org.springframework.web.multipart.MultipartFile;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.io.IOException;

public class FileValidator implements ConstraintValidator<ValidFile, MultipartFile> {
    private final Tika tika = new Tika();
    private List<String> extensions;
    private List<String> mimeTypes;
    private long maxSize;

    @Override
    public void initialize(ValidFile constraintAnnotation) {
        extensions = List.of(constraintAnnotation.extensions());
        mimeTypes = List.of(constraintAnnotation.mimeTypes());
        maxSize = constraintAnnotation.maxSize();
    }

    @Override
    public boolean isValid(MultipartFile file, ConstraintValidatorContext context) {
        if (file == null || file.isEmpty()) {
            return true;
        }
        // 文件大小验证
        if (file.getSize() > maxSize) {
            return false;
        }
        // 文件扩展名验证
        // String fileName = file.getOriginalFilename();
        // String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
        String fileExtension = FilenameUtils.getExtension(file.getOriginalFilename());
        if( StringUtils.isNotBlank(fileExtension) && extensions.contains(fileExtension .toLowerCase())){
            retrun true;
        }
        // 这里使用apache tika验证文件mime,实际是通过文件头内容中的魔法数来验证的
        var detect = tika.detect(TikaInputStream.get(file.getInputStream()));
        return mimeTypes.contains(detect);
    }
}

注: apache tika 是一个开源的文档识别工具,它可以自动检测文件类型并提取文件内容。使用 Tika,可以方便地确定文件类型和拓展名,从而根据文件类型来执行相应的操作,具体使用不是本文内容不再介绍了.

3. 使用注解

最后在Spring Boot的Controller中使用这个注解来校验文件。

import org.springframework.http.ResponseEntity;
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 javax.validation.constraints.NotNull;

@RestController
public class FileUploadController {

    @PostMapping("/upload")
    public ResponseEntity<?> uploadFile(@RequestParam("file") @NotNull @ValidFile(extensions = {"jpg", "png"}, mimeTypes = {"image/jpeg", "image/png"}, maxSize = 2 * 1024 * 1024) MultipartFile file) {
        // 文件处理逻辑
        return ResponseEntity.ok("File uploaded successfully");
    }
}

@ValidFile注解验证文件的扩展名是否为"jpg"或"png",MIME类型是否为"image/jpeg"或"image/png",以及文件大小是否不超过2MB。如果文件不符合这些要求,SpringBoot将自动返回400 Bad Request响应。

  • 以上注解合并了三个验证逻辑, 会导致验证失败是提示语不具体, 如有改需求,可以将其拆分成为三个注解.

到此这篇关于SpringBoot实现自定义注解用于文件验证的详细过程(大小、扩展名、MIME类型)的文章就介绍到这了,更多相关SpringBoot自定义注解文件验证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot控制反转与Bean对象的方法

    Springboot控制反转与Bean对象的方法

    文章介绍了Spring Boot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括通过@ComponentScan和@Bean注解的方式,并讨论了Bean的依赖注入方法,如构造器注入、Setter注入和字段注入,感兴趣的朋友一起看看吧
    2025-03-03
  • java中线程的sleep()方法和yield()方法的区别

    java中线程的sleep()方法和yield()方法的区别

    本文主要介绍了java中线程的sleep()方法和yield()方法的区别,Thread类的sleep()方法使线程休眠指定时间,不释放锁,而yield()提示调度器当前线程愿意让出CPU资源,不保证立即切换线程,感兴趣的可以了解一下
    2024-10-10
  • 实例详解Java库中的LocalDate类

    实例详解Java库中的LocalDate类

    在做报表统计时,需要对指定时间内的数据做统计,则需要使用到时间日期API,下面这篇文章主要给大家介绍了关于Java库中LocalDate类的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • MyBatis的逆向工程详解

    MyBatis的逆向工程详解

    这篇文章主要介绍了MyBatis的逆向工程详解,详细的介绍了逆行工程的概念和实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 阿里面试Nacos配置中心交互模型是push还是pull原理解析

    阿里面试Nacos配置中心交互模型是push还是pull原理解析

    这篇文章主要为大家介绍了阿里面试Nacos配置中心交互模型是push还是pull原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 基于Java实现图形验证码工具类

    基于Java实现图形验证码工具类

    这篇文章主要为大家详细介绍了如何基于Java实现图形验证码工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-11-11
  • JUnit 5 中的 @ClassTemplate 实战攻略

    JUnit 5 中的 @ClassTemplate 实战攻略

    这篇文章主要介绍了JUnit 5 中的 @ClassTemplate 实战指南,在本文中,我们从基础概念出发,进一步深入了解@ClassTemplate的使用方式,重点考察了提供者如何为单个测试类提供多个执行上下文,需要的朋友可以参考下
    2025-12-12
  • Java中实现可拖放图片剪裁入门教程

    Java中实现可拖放图片剪裁入门教程

    这篇文章主要介绍了Java中实现可拖放图片剪裁入门教程,本文写给新手,分步骤讲解如何实现图片裁剪,并对每步的代码作注释,需要的朋友可以参考下
    2015-01-01
  • EditPlus运行java时从键盘输入数据的操作方法

    EditPlus运行java时从键盘输入数据的操作方法

    这篇文章主要介绍了EditPlus运行java时从键盘输入数据的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • SpringBoot中动态数据源配置与使用详解

    SpringBoot中动态数据源配置与使用详解

    在现代应用中,处理多数据源是常见的需求,在 Spring Boot 中,这样的需求可以通过动态数据源来轻松实现,本篇博客将详细介绍如何在 Spring Boot 中配置和使用动态数据源,并演示如何切换到指定的数据源,需要的朋友可以参考下
    2024-10-10

最新评论