spring boot通过Constraint和ConstraintValidator自定义参数校验注解 文件上传前置校验注解 validMessage

本文主要是介绍spring boot通过Constraint和ConstraintValidator自定义参数校验注解 文件上传前置校验注解 validMessage,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Constraint注解

在spring boot进行开发的时候,有时需要对请求的参数进行校验, 而@Constraint可以实现自定义的校验注解。

Spring boot自定义参数校验注解

1. 如果Spring boot是2.3.0之后的版本,需要引入新的依赖
		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
2. 自定义注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MultipartFileValidator.class)
public @interface MultipartFileUploadPreCheck {String DEFAULT_MAXSIZE = "-1";/*** AliasFor("endsWith")*/
//    FileUtils.Type[] value() default {};/*** 支持的文件后缀类型,默认全部,AliasFor("value")*/FileUtils.Type[] allowFileType() default {};/*** 文件后缀是否区分大小写*/boolean ignoreCase() default true;/*** 上传的文件是否允许为空*/boolean allowEmpty() default false;/*** Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or* kilobytes respectively.<br/>* 默认不限制但必须小于等于SpringMVC中文件上传配置*/String maxSize() default DEFAULT_MAXSIZE;/*** Min file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or* kilobytes respectively. default byte*/String minSize() default "0MB";String message() default "The uploaded file is not verified.";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}
3. FileUtils.Type文件
    @RequiredArgsConstructor(access = AccessLevel.PROTECTED)public static enum Type {/*** json*/JSON("json"),/*** JEPG.*/JPEG("FFD8FF"),JPG("FFD8FF"),/*** PNG.*/PNG("89504E47"),/*** GIF.*/GIF("47494638"),/*** TIFF.*/TIFF("49492A00"),/*** Windows Bitmap.*/BMP("424D"),/*** CAD.*/DWG("41433130"),/*** Adobe Photoshop.*/PSD("38425053"),/*** Rich Text Format.*/RTF("7B5C727466"),/*** XML.*/XML("3C3F786D6C"),/*** HTML.*/HTML("68746D6C3E"),/*** CSS.*/CSS("48544D4C207B0D0A0942"),/*** JS.*/JS("696B2E71623D696B2E71"),/*** Email [thorough only].*/EML("44656C69766572792D646174653A"),/*** Outlook Express.*/DBX("CFAD12FEC5FD746F"),/*** Outlook (pst).*/PST("2142444E"),/*** MS Word/Excel.* XLS_DOC:ppt,doc,xls* XLSX_DOCX:xlsx*/XLS("D0CF11E0"), XLSX("504B0304"),DOC("D0CF11E0"), DOCX("504B0304"),/*** Visio*/VSD("d0cf11e0a1b11ae10000"),/*** MS Access.*/MDB("5374616E64617264204A"),/*** WPS文字wps、表格et、演示dps都是一样的*/WPS("d0cf11e0a1b11ae10000"),/*** torrent*/TORRENT("6431303A637265617465"),/*** WordPerfect.*/WPD("FF575043"),/*** Postscript.*/EPS("252150532D41646F6265"),/*** Adobe Acrobat.*/PDF("255044462D312E"),/*** Quicken.*/QDF("AC9EBD8F"),/*** Windows Password.*/PWL("E3828596"),/*** ZIP Archive.*/
//        ZIP("504b0304140000000800"),/*** RAR Archive.*/RAR("52617221"),/*** JSP Archive.*/JSP("3C2540207061676520"),/*** JAVA Archive.*/JAVA("7061636B61676520"),/*** CLASS Archive.*/CLASS("CAFEBABE0000002E00"),
//        /**
//         * JAR Archive.
//         */
//        JAR("504b03040a0000000000"),/*** MF Archive.*/MF("4D616E69666573742D56"),/*** EXE Archive.*/EXE("4D5A9000030000000400"),/*** CHM Archive.*/CHM("49545346030000006000"),/*** Wave.*/WAV("57415645"),/*** AVI.*/AVI("41564920"),/*** Real Audio.*/RAM("2E7261FD"),/*** Real Media.*/RM("2E524D46"),/*** MPEG (mpg).*/MPG("000001BA"),/*** Quicktime.*/MOV("6D6F6F76"),/*** Windows Media.*/ASF("3026B2758E66CF11"),/*** MIDI.*/MID("4D546864"),/*** MP4.*/MP4("00000020667479706d70"),/*** MP3.*/MP3("49443303000000002176"),/*** FLV.*/FLV("464C5601050000000900"),/*** TXT:txt,docx*/TXT("0000000000000000000000000000");@Getterprivate final String value;private static HashMap<String, Type> codeValueMap = new HashMap<>(47);static {for (FileUtils.Type currentOne : FileUtils.Type.values()) {codeValueMap.put(currentOne.getValue(), currentOne);}}public static FileUtils.Type getInstance(int code) {return codeValueMap.get(code);}public static boolean exists(int code) {return codeValueMap.containsKey(code);}}
3. 编写自定义注解处理文件
public class MultipartFileValidator implements ConstraintValidator<MultipartFileUploadPreCheck, MultipartFile> {@Autowiredprivate MultipartProperties multipartProperties;private long maxSize = -1;private long minSize = 0;private MultipartFileUploadPreCheck multipartFileUploadPreCheck;private final ArrayList<FileUtils.Type> extension = new ArrayList<>();@Overridepublic void initialize(MultipartFileUploadPreCheck constraintAnnotation) {this.multipartFileUploadPreCheck = constraintAnnotation;//支持的文件扩展名集合
//        Collections.addAll(extension, multipartFileUploadPreCheck.value());Collections.addAll(extension, multipartFileUploadPreCheck.allowFileType());//文件上传的最大值if (constraintAnnotation.maxSize().equals(MultipartFileUploadPreCheck.DEFAULT_MAXSIZE)) {//默认最大值采用Spring中配置的单文件大小DataSize maxFileSize = multipartProperties.getMaxFileSize();this.maxSize = parseSize(maxFileSize.toString());} else {this.maxSize = parseSize(constraintAnnotation.maxSize());}//文件上传的最小值this.minSize = parseSize(constraintAnnotation.minSize());}private long parseSize(String size) {Assert.hasLength(size, "Size must not be empty");size = size.toUpperCase();long length = Long.parseLong(size.substring(0, size.length() - 2));if (size.endsWith("KB")) {return length * 1024;}if (size.endsWith("MB")) {return length * 1024 * 1024;}return Long.parseLong(size);}/*** 多个文件也可以 效验* @param multipartFiles* @param cvc* @return*/@SneakyThrowspublic boolean isValids(MultipartFile[] multipartFiles, ConstraintValidatorContext cvc) {//上传的文件是空的情况if (Objects.isNull(multipartFiles)) {if (multipartFileUploadPreCheck.allowEmpty()) {return true;}validMessage("上传文件不能为空", cvc);return false;}for (MultipartFile multipartFile : multipartFiles) {boolean valid = isValid(multipartFile, cvc);if (!valid) {return false;}}return true;}@SneakyThrows@Overridepublic boolean isValid(MultipartFile multipartFile, ConstraintValidatorContext cvc) {String fieldName = multipartFile.getName();//上传的文件是空的情况if (multipartFile.isEmpty()) {if (multipartFileUploadPreCheck.allowEmpty()) {return true;}validMessage("上传文件不能为空" + ",参数名:" + fieldName, cvc);return false;}//上传的文件不是空的情况,验证其他条件是否成立//获取文件名,如果上传文件后缀名不区分大小写则统一转成小写String originalFilename = multipartFile.getOriginalFilename();if (multipartFileUploadPreCheck.ignoreCase()) {originalFilename = originalFilename.toLowerCase();}if (StringUtils.isBlank(originalFilename)){validMessage("上传文件名不能为空", cvc);return false;}// 先通过后缀名过滤一部分明显错误的, 因为读取文件流获取文件头信息 比较消耗资源
//        String fileSuffixName = originalFilename.substring(originalFilename.lastIndexOf('.') + 1);
//        List<String> allowedFileSuffixNames = extension.stream().map(e -> e.name().toLowerCase(Locale.ROOT)).collect(Collectors.toList());
//        if (StringUtils.isNotBlank(fileSuffixName) && allowedFileSuffixNames.stream().noneMatch(e -> e.equals(fileSuffixName))) {
//            validMessage("上传文件类型不符合要求" + ",参数名:" + fieldName, cvc);
//            return false;
//        }FileUtils.Type type = FileUtils.getType(multipartFile.getInputStream());if (extension.size() > 0 && extension.stream().noneMatch(e -> e.equals(type))) {validMessage("上传文件类型不符合要求" + ",参数名:" + fieldName, cvc);return false;}//上传文件字节数long size = multipartFile.getSize();if (size < this.minSize) {validMessage("上传文件不能小于指定最小值" + ",参数名:" + fieldName, cvc);return false;}if (size > this.maxSize) {validMessage("上传文件不能大于指定最大值" + ",参数名:" + fieldName, cvc);return false;}return true;}private void validMessage(String message, ConstraintValidatorContext cvc) {cvc.disableDefaultConstraintViolation();cvc.buildConstraintViolationWithTemplate(message).addConstraintViolation();}}

这篇关于spring boot通过Constraint和ConstraintValidator自定义参数校验注解 文件上传前置校验注解 validMessage的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041806

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis