@FileLimit – AOP最佳实践:上传文件大小限制
@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
拦截成功!完结 !
@FileLimit – AOP最佳实践:上传文件大小限制的更多相关文章
- 解决phpmyadmin上传文件大小限制的配置方法
解决phpmyadmin上传文件大小限制的配置方法 phpmyadmin导入SQL文件时涉及到phpmyadmin上传文件大小限制问题,默认phpmyadmin上传文件大小为2M,如果想要phpmya ...
- 解决ASP.NET上传文件大小限制
第一种方法,主要适用于IIS6.0版本 一.修改配置Web.Config文件中的httpRuntime节点对于asp.net,默认只允许上传4M文件,增加如下配置,一般可以自定义最大文件大小.一.修改 ...
- 兼容各浏览器的js判断上传文件大小
由于项目需要,在网上找了一个JS判断上传文件大小的程序,经测试兼容IE6-,Firefox10,Opera11.,safari5.,chrome17 <!DOCTYPE html> < ...
- 【荐】PHP上传文件大小限制大全
在php.ini里面可以设置最大上传文件大小 解决方法: 第一: 在php.ini里面查看如下行: upload_max_filesize = 8M post_max_size = 10M memor ...
- nginx:413 Request Entity Too Large 及 修改 PHP上传文件大小配置
开发环境:CentOS + Nginx + PHP + MySql + phpMyAdmin 在用 phpMyAdmin 进行 sql 数据库导入的时候,经常需要上传比较大的 sql 数据文件,而这时 ...
- 修改PHP上传文件大小限制的方法
感谢分享,原文地址:http://www.cnblogs.com/newsouls/archive/2012/12/27/2835628.html 修改PHP上传文件大小限制的方法1. 一般的文件上传 ...
- php.ini修改php上传文件大小限制的方法详解
打开php.ini,首先找到file_uploads = on ;是否允许通过HTTP上传文件的开关.默认为ON即是开upload_tmp_dir ;文件上传至服务器上存储临时文件的地方,如果没指定就 ...
- php上传文件大小限制修改
打开php.ini 1.最大上传文件大小: upload_max_filesize=2M 改成自己需要的大小 2.最大post大小: post_max_size=2M 改成自己需要的大小,第二个一般比 ...
- 修改apache上传文件大小限制
PHP上传文件大小限制解决方法: 第一: 在php.ini里面查看如下行: upload_max_filesize = 8M post_max_size = 10M memory_limi ...
- wordpress修改上传文件大小限制
在为有的客户搭建 WordPress 网站时,有时会遇到因为所在的服务器限制了上传文件大小而无法上传较大的附件,WordPress的媒体文件上传可以看到,大多数都是2MB或者8MB.如果是图片的话可能 ...
随机推荐
- IdentityServer4 - v4.x .Net中的实践应用
认证授权服务的创建 以下内容以密码授权方式为例. 创建模拟访问DB各数据源类 为模拟测试准备的数据源. /// 假设的用户模型 public class TestUser { public strin ...
- [python] 基于matplotlib实现树形图的绘制
树形图Tree diagram (代码下载) 本文旨在描述如何使用Python实现基本的树形图.要实现这样的树形图,首先需要有一个数值矩阵.每一行代表一个实体(这里是一辆汽车).每列都是描述汽车的变量 ...
- [python] 基于blind-watermark库添加图片盲水印
blind-watermark是一个能够给图片添加/解析基于频域的数字盲水印的Python库.图像水印image watermark是指在图片里添加文本或图形,以标记图片的来源.但是图像水印会破坏原图 ...
- Spark详解(01) - Scala编程语言
Spark详解(01) - Scala编程语言概述 Scala官网:https://www.scala-lang.org/ 什么是Scala 从英文的角度来讲,Scala并不是一个单词,而是Scala ...
- .Net 6 使用 Consul 实现服务注册与发现 看这篇就够了
前言 在这几年的工作中,也经历过几个微服务项目,大多数都上了k8s,基本上都看不到Consul的身影,所以在工作之余折腾了下Consul,作为个人来讲还是得学习下,所以也就顺便通过文章来记录下学习过程 ...
- 【前端调试】- 借助Performance分析并优化性能
欢迎阅读本系列其他文章 [前端调试]- 更好的调试方式 VSCode Debugger [前端调试]- 断点调试的正确打开方式 介绍 首先简单过一下Performance的使用,打开网页点击控制台Pe ...
- P8618 [蓝桥杯 2014 国 B] Log 大侠
简要题意 给你一个长度为 \(n\) 的正整数序列 \(a\),有 \(m\) 个询问,每一个询问给出一个区间 \([l,r]\).定义函数 \(f(x)=\lfloor\log_{2}(x)+1\r ...
- 【分析笔记】Linux 内核自旋锁的理解和使用原则
自旋锁简单说明: 自旋锁主要解决在竞态并发下,保护执行时间很短的临界区.它只允许一个执行单位进入临界区,在该执行单位离开前,其它的执行单位将会在进入临界区前不停的循环等待(即所谓的自旋),直至该执行单 ...
- mysql 错误解决大法 Specified key was too long; max key length is 767 bytes
高版本mysql向低版本(5.7以下)导入sql时可能会发生此问题 开启索引最大长度 SET GLOBAL INNODB_LARGE_PREFIX = ON; 将表改为动态表SET GLOBAL in ...
- springboot FilterRegistrationBean 拦截器的使用
1.创建一个filter package com.ruoyi.weixin.user.interator; import com.ruoyi.common.utils.SecurityUtils; i ...