IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 使用aop、解析器处理自定义注解 -> 正文阅读

[Java知识库]使用aop、解析器处理自定义注解

先随便定义一个自定义注解

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LimitLength {

    int minLength() default 1;

    int maxLength() default 1;
}

这里预计用来限制字段的长度,本来最开始的设想是限制密码长度的(只是随便实现个功能,不要纠结加密、DTO的事),所以在加到方法上时(即下面aop处理时)仅仅处理了密码的长度。

@Aspect
@Component
public class LimitLengthAspect {

    @Before("@annotation(com.islands.common.aspect.annotation.LimitLength)")
    public void checkBefore(JoinPoint point)  {
        // 获取注解
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        LimitLength annotation = method.getDeclaredAnnotation(LimitLength.class);
        // 获取实体
        Object[] args = point.getArgs();
        for (Object arg : args) {
           if (arg instanceof User) {
               String password = ((User) arg).getPassword();
               Assert.isTrue(password.length() >= annotation.minLength() && password.length() <= annotation.maxLength(), "长度不符合标准!");
           }
        }
    }
}

这里做了一个前置通知,因为只有加了注解的情况下会被aop拦下所以没有对注解是否存在判空。

顺带一提,这里本来的设想是把注解加到参数上,但是不知道为啥aop拦不下,所以参数是用的是解析器处理的,本来是用的拦截器,但是拦截器里的入参拿到的参数名是arg0、arg1这种的,就放弃了。

下面的是用解析器形式处理的,处理把注解加到参数、属性上的情况。多个参数用DTO做入参的情况就不处理了。加在属性上时就没有限定一定是处理密码了,只要是加了注解的属性就限制长度。因为做了全局异常捕获,所以长度不对就直接用断言抛了。

@Component
public class LimitLengthResolver implements HandlerMethodArgumentResolver {

	/**
     * 处理器,这里是在处理参数、属性上的LimitLength注解
     *
     * @date 2022-04-26 10:44
     * @param methodParameter methodParameter
     * @return  是否处理
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
       // 获取所有参数的类型,这里处理的是注解在属性上时的情况
        Class<?> parameterType = methodParameter.getParameterType();
        Field[] fields = parameterType.getDeclaredFields();
        for (Field field : fields) {
            LimitLength annotation = field.getDeclaredAnnotation(LimitLength.class);
            if (ObjectUtil.isNotEmpty(annotation)) {
                return true;
            }
        }

        // 获取所有参数,这里处理的是注解在参数上时的情况
        Parameter methodParam = methodParameter.getParameter();
        LimitLength annotation = methodParam.getDeclaredAnnotation(LimitLength.class);
        ResponseBody responseBody = methodParam.getDeclaredAnnotation(ResponseBody.class);
        if (ObjectUtil.isNotEmpty(annotation) && ObjectUtil.isNull(responseBody)) {
            return true;
        }
        return false;
    }

	/**
     * 处理器,这里是在处理参数、属性上的LimitLength注解
     *
     * @date 2022-04-26 10:44
     * @param methodParameter methodParameter
     * @param modelAndViewContainer modelAndViewContainer
     * @param nativeWebRequest nativeWebRequest
     * @param webDataBinderFactory webDataBinderFactory
     * @return  参数
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        // HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);

        // 获取所有参数的类型,这里处理的是注解在属性上时的情况
        Class<?> parameterType = methodParameter.getParameterType();
        Field[] fields = parameterType.getDeclaredFields();
       	for (Field field : fields) {
            LimitLength annotation = field.getAnnotation(LimitLength.class);
            if (ObjectUtil.isNotEmpty(annotation)) {
                // 如果存在这个注解,则直接从入参里获取这个param
                String param = request.getParameter(field.getName());
                if (ObjectUtil.isEmpty(param)) {
                    param = "";
                }
                Assert.isTrue(param.length() >= annotation.minLength() && param.length() <= annotation.maxLength(), "长度有误!");
                return param;
            }
        }

        // 获取所有参数,这里处理的是注解在参数上时的情况
        Parameter methodParam = methodParameter.getParameter();
        LimitLength annotation = methodParam.getDeclaredAnnotation(LimitLength.class);
        if (ObjectUtil.isNotEmpty(annotation)) {
        	// 如果存在这个注解,则直接从入参里获取这个param
            String param = request.getParameter(methodParam.getName());
            if (ObjectUtil.isEmpty(param)) {
            	ResponseBody methodAnnotation = methodParameter.getMethodAnnotation(ResponseBody.class);
                Assert.isNull(methodAnnotation, "LimitLength注解仅能限制单个的参数长度,请将注解加在属性上!");
                param = "";
            }
            Assert.isTrue(param.length() >= annotation.minLength() && param.length() <= annotation.maxLength(), "长度有误!");
            return param;
        }
        return null;
    }

写一个config把解析器加上。

@Configuration
public class SpringConfig implements WebMvcConfigurer {

    @Autowired
    private LimitLengthResolver limitLengthResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(limitLengthResolver);
    }
}

悄咪咪的说一下ObjectUtil是用的hutool的,当然你用其他的帮助类或者手动判空也行。

可能有很多地方写的会比较乱,某些地方可能有更好的获取注解、属性、参数的方法,欢迎大佬指正(诶嘿)。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:11:09  更:2022-04-27 11:12:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:24:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码