@FileLimit 结构分析
1、FileLimitUnit 定义枚举:文件的单位
public enum FileLimitUnit { KB, MB, GB }
2、定义注解
import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; /** * @Author :zanglk * @DateTime :2022/1/25 09:49 * @Description :FileLimit 注解,内置参数value,max,以及文件单位 * @Notes :To change this template:Click IDEA-Preferences to search 'File Templates' */ @Documented @Target(ElementType.METHOD) // 作用与方法上 @Retention(RetentionPolicy.RUNTIME) // RUNTIME: 在运行时有效(即运行时保留) public @interface FileLimit { @AliasFor("max") // @AliasFor 表示其可与max互换别名:当注解指定value时,为max赋值 int value() default 5; // 定义单个文件最大限制 @AliasFor("value") // @AliasFor 表示其可与value互换别名:当注解指定max是,为value赋值 int max() default 5; // 文件单位,默认定义为MB FileLimitUnit unit() default FileLimitUnit.MB; }
3、注解使用
任意方法添加,如果不传入value,就使用注解默认值5。 @FileLimit(value = 25,unit = FileLimitUnit.MB) @FileLimit(unit = FileLimitUnit.MB) @FileLimit
4、AOP拦截控制
注意 AOP拦截我在输出异常信息时,转换了文件大小,所以我使用我自己的工具类,这里我就不贴代码了。
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; @Aspect @Component public class FileLimitAop { // 定义默认的单个文件最大限制 5MB 。5Mb = 5 * 1024 * 1024 byte private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 注意,这里要指定注解的全限定类名。不然无法进入AOP拦截自定义注解FileLimit @Pointcut("@annotation(com.zanglikun.springdataredisdemo.aop.fileLimitAop.FileLimit)") public void pointcut() { } /** * 方法体执行之前执行 */ @Before("pointcut()") public void beforeLog(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); FileLimit annotation = AnnotationUtils.getAnnotation(signature.getMethod(), FileLimit.class); if (null == annotation) { return; } // 执行文件检查 fileSizeLimit(joinPoint, annotation); } // 判定文件大小是否合格,如果不合格,直接跑出自定义异常FileLimitException。进而阻塞方法正常进行。 private void fileSizeLimit(JoinPoint joinPoint, FileLimit annotation) { // 获取AOP签名 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取注解的指定最大文件大小 long maxFileSize = getAnnotationMaxFileSize(annotation); // 通过AOP签名 获取接口参数,调用方法获取文件 MultipartFile multipartFile = getMultipartFile(signature.getParameterNames(), signature.getParameterTypes(), joinPoint.getArgs()); if (null != multipartFile) { if (0 == multipartFile.getSize()) { throw new FileLimitException("文件数据(大小为0)异常."); } if (multipartFile.getSize() > maxFileSize) { String msg = "文件大小不得超过 " + annotation.max() + annotation.unit().toString(); throw new FileLimitException(msg+" ,当前文件大小是 "+FileSizeOut.printFileSize(multipartFile.getSize())); } } } // 获取使用注解指定最大文件大小。如果没有指定文件大小,就用默认值 public long getAnnotationMaxFileSize(FileLimit fileLimit) { if (null == fileLimit) { return MAX_FILE_SIZE; } switch (fileLimit.unit()) { case MB: return (long) fileLimit.max() * 1024 * 1024; case KB: return (long) fileLimit.max() * 1024; default: return MAX_FILE_SIZE; } } // 使用AOP获取目标请求方法携带的参数。我们当前只需要解析File private MultipartFile getMultipartFile(String[] paramNames, Class[] paramTypes, Object[] paramObjs) { for (int i = 0; i < paramNames.length; i++) { if (paramTypes[i] != MultipartFile.class) { continue; } return (MultipartFile) paramObjs[i]; } return null; } }
测试
测试前,请添加或修改配置文件,避免因为Servlet大小限制了。
# 限制Tomcat Servlet单文件大小、以及总请求大小,-1则不限制! spring.servlet.multipart.max-file-size=-1 spring.servlet.multipart.max-request-size=-1
@RestController @RequestMapping("/testFileLimit") public class TestFileLimit { @RequestMapping("/upload") //@FileLimit(value = 25,unit = FileLimitUnit.MB) //@FileLimit(unit = FileLimitUnit.MB) @FileLimit public void upLoad(MultipartFile file) { System.out.println("请求进入喽"); } }
我上传一个视频文件461.0MB
2022-10-25 12:55:56.245 ERROR 42691 --- [nio-8081-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.zanglikun.springdataredisdemo.aop.FileLimitException: 文件大小不得超过 5MB ,当前文件大小是 461.0MB] with root cause com.zanglikun.springdataredisdemo.aop.FileLimitException: 文件大小不得超过 5MB ,当前文件大小是 461.0MB
拦截成功!完结
标签:文件大小,MB,max,AOP,import,annotation,FileLimit From: https://www.cnblogs.com/kaixin001/p/16948252.html