好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

SpringBoot 上传文件判空以及格式检验流程

基于jsr303 通过自定义注解实现,实现思路:

存在一些瑕疵,后续补充完善。

加入依赖

部分版本已不默认自动引入该依赖,选择手动引入

?

1

2

3

4

< dependency >

     < groupId >org.springframework.boot</ groupId >

     < artifactId >spring-boot-starter-validation</ artifactId >

</ dependency >

创建自定义注解以及实现类

目录结构:

FileNotEmpty 自定义注解 FileNotEmptyValidator 单文件校验 FilesNotEmptyValidator 多文件校验

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

/**

  * jsr303 文件格式校验注解

  *

  * @author maofs

  * @version 1.0

  * @date 2021 -11-29 10:16:03

  */

@Documented

@Constraint (

         validatedBy = {FileNotEmptyValidator. class , FilesNotEmptyValidator. class }

)

@Target ({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})

@Retention (RetentionPolicy.RUNTIME)

public @interface FileNotEmpty {

     /**

      * Message string.

      *

      * @return the string

      */

     String message() default "文件格式不正确" ;

     /**

      * 校验组

      *

      * @return the class [ ]

      */

     Class<?>[] groups() default {};

     /**

      * Payload class [ ].

      *

      * @return the class [ ]

      */

     Class<? extends Payload>[] payload() default {};

     /**

      * 需要校验的格式数组

      *

      * @return the string [ ]

      */

     String[] format() default {};

     /**

      * 是否必填 为false时文件为空则不校验格式,不为空则校验格式

      * 为true时文件不能为空且需要验证格式

      *

      * @return the boolean

      */

     boolean required() default true ;

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

/**

  * 单文件校验

  *

  * @author maofs

  * @version 1.0

  * @date 2021 -11-29 10:16:03

  */

public class FileNotEmptyValidator implements ConstraintValidator<FileNotEmpty, MultipartFile> {

     private Set<String> formatSet = new HashSet<>();

     private boolean required;

     @Override

     public void initialize(FileNotEmpty constraintAnnotation) {

         String[] format = constraintAnnotation.format();

         this .formatSet = new HashSet<>(Arrays.asList(format));

         this .required = constraintAnnotation.required();

     }

     @Override

     public boolean isValid(MultipartFile multipartFile, ConstraintValidatorContext constraintValidatorContext) {

         if (multipartFile == null || multipartFile.isEmpty()) {

             return !required;

         }

         String originalFilename = multipartFile.getOriginalFilename();

         assert originalFilename != null ;

         String type = originalFilename.substring(originalFilename.lastIndexOf( '.' ) + 1 ).toLowerCase();

         if (!formatSet.isEmpty()) {

             return formatSet.contains(type);

         }

         return true ;

     }

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

/**

  *  多文件校验

  *

  * @author maofs

  * @version 1.0

  * @date 2021 -11-29 10:16:03

  */

public class FilesNotEmptyValidator implements ConstraintValidator<FileNotEmpty, MultipartFile[]> {

     private Set<String> formatSet = new HashSet<>();

     private boolean required;

     @Override

     public void initialize(FileNotEmpty constraintAnnotation) {

         String[] format = constraintAnnotation.format();

         this .formatSet = new HashSet<>(Arrays.asList(format));

         this .required = constraintAnnotation.required();

     }

     @Override

     public boolean isValid(MultipartFile[] multipartFiles, ConstraintValidatorContext constraintValidatorContext) {

         if (multipartFiles == null || multipartFiles.length == 0 ) {

             return !required;

         }

         for (MultipartFile file : multipartFiles) {

             String originalFilename = file.getOriginalFilename();

             assert originalFilename != null ;

             String type = originalFilename.substring(originalFilename.lastIndexOf( '.' ) + 1 ).toLowerCase();

             if (formatSet.isEmpty() || !formatSet.contains(type)) {

                 return false ;

             }

         }

         return true ;

     }

}

全局异常处理

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

/**

  * 统一异常处理

  *

  * @author maofs

  * @version 1.0

  * @date 2021 -11-29 10:16:03

  */

@ControllerAdvice

public class ExceptionHandle {

     private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle. class );

       

     @ExceptionHandler (value = Exception. class )

     @ResponseBody

     public Result<String> handle(Exception e) {

         logger.error(e.getMessage());

         StringBuilder stringBuilder = new StringBuilder();            

             //jsr303异常

           if (e instanceof ConstraintViolationException) {

             ConstraintViolationException ex = (ConstraintViolationException)e;

             Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();

             for (ConstraintViolation<?> constraintViolation : constraintViolations) {

                 stringBuilder.append(constraintViolation.getMessageTemplate());

             }

         } else if (e instanceof BindException) {

             BindException bindException = (BindException)e;

             stringBuilder.append(bindException.getFieldErrors()

                 .stream()

                 .map(FieldError::getDefaultMessage)

                 .collect(Collectors.joining( "," )));

         } else {

             stringBuilder.append( "未知错误:" ).append( "请联系后台运维人员检查处理!" );          

         }

         return   ResultUtil.fail(stringBuilder.toString());

     }   

}

使用示例

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

/**

  * 文件上传示例接口

  *

  * @author maofs

  * @version 1.0

  * @date 2021 -11-19 16:08:26

  */

@RestController

@Validated

@RequestMapping ( "/annex" )

public class AnnexController {

  @Resource

  private IAnnexService annexService;

    /**

      * 文件上传示例1

      *

      * @param uploadDTO the upload dto

      * @return the result

      */

     @PostMapping (value = "/upload1" )

     public Result<String> upload( @Valid AnnexUploadDTO uploadDTO) {

         return Boolean.TRUE.equals(annexService.upload(uploadDTO)) ? ResultUtil.success() : ResultUtil.fail();       

     }

    

    /**

      * 文件上传示例2

      *

      * @param number      项目编号

      * @param pictureFile 图片文件

      * @param annexFile   附件文件

      * @return result result

      */

     @PostMapping (value = "/upload2" )

     public Result<String> upload( @NotBlank ( @FileNotEmpty (format = { "png" , "jpg" }, message = "图片为png/jpg格式" , required = false )

                                          MultipartFile pictureFile, @FileNotEmpty (format = { "doc" , "docx" , "xls" , "xlsx" }, message = "附件为doc/docx/xls/xlsx格式" , required = false )

                                          MultipartFile annexFile) {      

         return Boolean.TRUE.equals(annexService.upload( pictureFile, annexFile)) ? ResultUtil.success() : ResultUtil.fail();

     }

    

     @Data

     static class AnnexUploadDTO{

         @FileNotEmpty (format = { "pdf" , "doc" , "zip" }, message = "文件为pdf/doc/zip格式" )

         private MultipartFile[] file;

     }

}

结果展示

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/weixin_43931248/article/details/122000087

查看更多关于SpringBoot 上传文件判空以及格式检验流程的详细内容...

  阅读:85次