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实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有