Spring boot 2.1 自定义注解拦截器
程序员文章站
2022-04-30 16:35:29
...
- 需求
系统有很多需要上传文件的接口,这些接口需要的文件格式都是jpg格式的,所以想把这一部分提出来,可以用拦截器的方式,但是我想要的是在Controller中的某个方法上加个注解就能有这样的功能,而不是去配置拦截器URL之类的
- 实现
显然需要用到 AOP
- 代码
自定义注解
import java.lang.annotation.*;
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface ImageNeed {
}
配置切面
import com.truthso.dto.Result;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
@Aspect
@Configuration
public class FileAspect {
private static final Logger logger = LoggerFactory.getLogger(FileAspect.class);
@Pointcut("execution(* com.truthso.monitor.consumer.controller.*(..))")
public void executeService() {
}
@Around("@annotation(com.truthso.monitor.consumer.annotation.ImageNeed)")
public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("------------------------------------------------------");
logger.info("request from :{} ", request.getRemoteAddr());
logger.info("request url :{} ", request.getRequestURL().toString());
logger.info("request method :{} ", request.getMethod());
logger.info("response method :{} ", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
logger.info("request params :{} ", Arrays.toString(joinPoint.getArgs()));
logger.info("------------------------------------------------------");
String contentType = request.getContentType();
if (null == contentType || !contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/")) {
return new Result(201, "please upload file");
}
MultipartResolver resolver = new StandardServletMultipartResolver();
MultipartHttpServletRequest fileRequest = resolver.resolveMultipart(request);
MultipartFile file = fileRequest.getFile("file");
if (file == null) {
return new Result(202, "please upload file");
}
if (file.getSize() == 0) {
return new Result(203, "file size is 0");
}
return joinPoint.proceed();
}
}
- 使用方法
@RestController
@RequestMapping("old")
public class OldController {
private static final Logger logger = LoggerFactory.getLogger(OldController.class);
@ImageNeed
@RequestMapping("compare")
public Result compare(MultipartFile file, HttpServletRequest req) throws Exception {
String format = sdf.format(new Date());
String realPath = req.getServletContext().getRealPath("/upload") + format;
File folder = new File(realPath);
if (!folder.exists()) {
folder.mkdirs();
}
String oldName = file.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
File image = new File(folder, newName);
file.transferTo(image);
// do something
image.delete();
return Result.successResult();
}
- 注意的问题
- FileAspect 类需要用 @Configuration 注解让 Spring boot 能扫描到
- 定义切点 @Pointcut 具体格式可以百度
- 只有 @Around 才有 ProceedingJoinPoint ,才有 joinPoint.proceed() 方法,Befor 和 After 都没有
- 在 方法里面将 HttpServletRequest 转换成 MultipartHttpServletRequest 的方式
- 后续需要加深对 AOP 实现等的理解
推荐阅读
-
Spring Boot项目实战之拦截器与过滤器
-
[Spring Boot]使用自定义注解统一请求返回值
-
浅谈Spring自定义注解从入门到精通
-
三、解决Spring MVC拦截器导致静态资源访问失败(基于java注解配置)
-
spring boot使用自定义的线程池执行Async任务
-
Spring-Boot使用嵌入式容器,那怎么配置自定义Filter呢
-
spring-boot-2.0.3不一样系列之番外篇 - 自定义session管理,绝对有值得你看的地方
-
Spring boot 学习笔记 1 - 自定义错误
-
IDEA开发spring boot应用时 application.yml 或 application.properties 自定义属性提示
-
浅谈Spring Boot 属性配置和自定义属性配置