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

目录
  • 加入依赖
  • 创建自定义注解以及实现类
  • 全局异常处理
  • 使用示例
  • 结果展示

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

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

加入依赖

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

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

目录结构:

  • FileNotEmpty 自定义注解
  • FileNotEmptyValidator 单文件校验
  • FilesNotEmptyValidator 多文件校验
/**
 * 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;
/**
 * 单文件校验
 *
 * @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;
    }
}
/**
 *  多文件校验
 *
 * @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;
    }
}

全局异常处理

/**
 * 统一异常处理
 *
 * @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());
    }
}

使用示例

/**
 * 文件上传示例接口
 *
 * @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;
    }
}

结果展示

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

(0)

相关推荐

  • SpringBoot文件上传控制及Java 获取和判断文件头信息

    之前在使用SpringBoot进行文件上传时,遇到了很多问题.于是在翻阅了很多的博文之后,总算将上传功能进行了相应的完善,便在这里记录下来,供自己以后查阅. 首先,是建立一个标准的SpringBoot 的工程,这里使用的IDE是Intellij Idea,为了方便配置,将默认的配置文件替换为了application.yml. 1.在index.html中进行文件上传功能,这里使用的文件上传方式是ajax,当然也可以按照自己的具体要求使用传统的表单文件上传. <!DOCTYPE html> &l

  • Springboot文件上传功能简单测试

    在static文件夹中创html页面 内容为: <html> <head></head> <body> <form action="/fileuploadContorller" method="post" enctype="multipart/form-data"> <input type="file" name="file"/> &l

  • springboot 参数格式校验操作

    springboot 参数格式校验 @Validated 字面意思校验 @RequestBody 该注解不用多说,意思是接收为json格式的参数 @Validated 字面意思校验, 需要配合@NotBlank 或者 @NotNull 注解才能生效 进入到请求体参数中. springboot 参数注解校验 1.添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s

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

    目录 加入依赖 创建自定义注解以及实现类 全局异常处理 使用示例 结果展示 基于jsr303 通过自定义注解实现,实现思路: 存在一些瑕疵,后续补充完善. 加入依赖 部分版本已不默认自动引入该依赖,选择手动引入 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </d

  • SpringBoot上传文件并配置本地资源映射来访问文件的实例代码

    1.准备工作 1.新建一个SpringBoot项目加上web依赖, 所有依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.thymeleaf</groupId&

  • vue+springboot上传文件、图片、视频及回显到前端详解

    目录 效果图 设计逻辑 数据库表 前端vue html js代码 前端思路 储存文件信息 上传文件对象 后端上传下载代码 完整代码 workinfo.vue SubmitHomeworkController 总结 效果图 预览: 设计逻辑 数据库表 前端vue html <div class="right-pannel"> <div class="data-box"> <!--上传的作业--> <div style=&quo

  • SpringBoot上传文件到本服务器 目录与jar包同级问题

    前言 看标题好像很简单的样子,但是针对使用jar包发布SpringBoot项目就不一样了. 当你使用tomcat发布项目的时候,上传文件存放会变得非常简单,因为你可以随意操作项目路径下的资源.但是当你使用SpringBoot的jar包发布项目的时候,你会发现,你不能像以前一样操作文件了.当你使用File file = new File()的时候根本不知道这个路径怎么办.而且总不能很小的项目也给它构建一个文件服务器吧.所以这次就来解决这样的问题. 不想知道细节的,可以直接跳转到最后封装的部分,里面

  • Springboot上传文件时提示405问题及排坑过程

    目录 Springboot上传文件时提示405 解决方案1 解决方案2 Springboot使用过程中遇到的一些问题 异常一 异常二:Mysql连接报错 异常三:整合Druid密码解密失败 Springboot上传文件时提示405 问题描述:上传文件时请求不通,状态码返回405,如下图:  问题分析:405 Method Not Allowed,请求行中指定的请求方法不能被用于请求相应的资源.该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表.简单说就是请求方法不支持

  • springboot上传文件过大的500异常解决

    修改appliaction.properties # 单个文件最大20m spring.servlet.multipart.max-file-size=20MB #一次请求最大100M spring.servlet.multipart.max-request-size=100MB 如果配置文件为appliaction.yml的这样配置文件: spring: servlet: multipart: maxFileSize: 20MB maxRequestSize: 100MB 500代码异常,在启

  • SpringBoot实现上传文件到AWS S3的代码

    简单记录一下在Springboot中上传文件到AWS S3存储服务的代码. 在 application.xml中添加aws相关配置: custom:   aws:     access-key: CHOBITACCESSKEY     secret-key: CHOBIT/THISIS006SECRET007Key/dotORG     bucket: zhyea     endpoint: www.zhyea.com:80 新建一个 AwsS3Componment类来执行上传文件操作: @Co

  • SpringBoot中的multipartResolver上传文件配置

    目录 multipartResolver上传文件配置 1.gradle配置 2.注册Bean SpringBoot MultipartResolver的坑 解决方案 multipartResolver上传文件配置 1.gradle配置 compile ('commons-io:commons-io:1.4') compile('commons-fileupload:commons-fileupload:1.2.1') 2.注册Bean @Bean(name = "multipartResolve

  • 解决springboot项目上传文件出现临时文件目录为空的问题

    最近写文件上传到服务器读取的代码,前端使用FormData上传,服务端用MultipartFile接收,自己测试了下MultipartFile对象有什么东西,结果一般属性都能出来,测试getInputStrea()方法的时候出现了以下错误,简单一看这是什么目录,从来没见过啊: 百度一番之后发现了这是临时文件存放的路径,不清楚根据什么去放在这个目录的,但是这个目录本机的确没有,linux系统下好像系统会10天清空一次,翻阅了API底下有这个 百度的时候也发现另外一个坑,spring配置的MaxIn

  • springboot以FTP方式上传文件到远程服务器

    一.html代码   <div class="layui-form-item"> <label class="layui-form-label">上传附件:</label> <div class="layui-input-block doc-litpic"> <button type="button" name="avatar" class="

随机推荐