zoukankan      html  css  js  c++  java
  • springAOP与注解

    https://412887952-qq-com.iteye.com/blog/2299732
    SpringMVC自带@Valid和@Validated两个注解可用来检查参数,但只能检查参数是bean的情况,对于参数是String或者Long类型的就不适用了,而且有时候这两个注解又突然失效了(没有仔细去调查过原因),对此,可以利用Spring的AOP和自定义注解,自己写一个参数校验的功能。
    注解是一个特殊的类,它可以给对象、参数、方法添加额外的这个类信息。说白了就是添加了更多的信息,我们可以称注解信息为元信息。我们通过java的运行时公共方法可以获取这些信息。所以,注解只有当你定义了专门的注解处理程序的时候才有用,否则一无是处!
    注解就是springAOP最好的使用例子。
    当请求过来的时候,spring框架的拦截器会检查被请求的controller方法接口中的注解,根据注解类型,调用不同的AOP处理程序进行处理。

    先定义一个注解:

    /**
     * 对 String 参数类型起非空校验作用
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.PARAMETER, ElementType.METHOD})
    @Inherited
    public @interface NotNull {
    
        String msg() default " 字段不能为null";
        String msg1() default " 字段不能为blank";
    }
    

    再写一个切面,处理被注解的参数:

    @Slf4j
    @Aspect
    @Component
    public class NotNullValidAspect {
    
         @Pointcut("execution(public * com.infoholdcity.parking.*.web..*(..)) && @annotation(com.infoholdcity.parking.common.annotation.NotNull)")
        public void checkParam(){}
    
        @Before("checkParam()")
        public void beforePointcut(JoinPoint joinPoint) {
            log.debug("参数验证中……");
            //获取参数对象
            Object[] args = joinPoint.getArgs();
            //获取方法参数
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Parameter[] parameters = signature.getMethod().getParameters();
            for (int i = 0; i < parameters.length; i++) {
                Parameter parameter = parameters[i];
    
                //HttpServletRequest、HttpServletResponse、HttpSession时,都不做处理
                if (parameter.getType().isAssignableFrom(HttpServletRequest.class) || parameter.getType().isAssignableFrom(HttpSession.class) ||
                        parameter.getType().isAssignableFrom(HttpServletResponse.class)) {
                    continue;
                }
    
                log.debug("参数类型:"+ parameter.getType().getName());
                log.debug("参数名:"+ parameter.getName());
    
                //该参数有该注解,且是String类型
                    NotNull notNull = parameter.getAnnotation(NotNull.class);
                if (notNull != null && String.class.isAssignableFrom(parameter.getType())) {
                    if (args[i] == null) {
                        throw new ParamBlankException(parameter.getName() + notNull.msg());
                    }else if(StringUtils.isBlank(args[i].toString())){
                        throw new ParamBlankException(parameter.getName() + notNull.msg1());
                    }
                    //TODO
                    continue;
                }
    
            }
        }
    
    }
    
    

    定义一个异常,用于捕获:

    /**
     * String参数为null或blank异常
     */
    public class ParamBlankException extends RuntimeException{
        public ParamBlankException() {
        }
    
        public ParamBlankException(String message) {
            super(message);
        }
    }
    

    全局异常处理器:

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        /**
         * 手机号,车牌号格式校验, 在自定义类参数前加 @Validated 即可生效
         * @param e
         * @return
         */
        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseBody
        public RestResponse<Object> exceptionMethod1(MethodArgumentNotValidException e) {
            RestResponse<Object> rr = new RestResponse<Object>();
            BindingResult bindingResult = e.getBindingResult();
            FieldError fieldError = bindingResult.getFieldError();
            rr.setStatus("500");
            rr.setMessage(fieldError.getField() + " " + fieldError.getDefaultMessage());
            return rr;
        }
    
    
    
        /**
         * 手机号,车牌号格式校验
         * @param e
         * @return
         */
        @ExceptionHandler(ParamBlankException.class)
        @ResponseBody
        public RestResponse<Object> exceptionMethod2(ParamBlankException e) {
            RestResponse<Object> rr = new RestResponse<Object>();
            rr.setStatus("500");
            rr.setMessage(e.getMessage());
            return rr;
        }
    
        @ExceptionHandler(Exception.class)
        @ResponseBody
        public RestResponse<Object> exceptionMethod(Exception ex) {
            RestResponse<Object> rr = new RestResponse<Object>();
            rr.setStatus("500");
            rr.setMessage("inner error of server." + ex.getMessage());
            return rr;
        }
    }
    

    接口里的注解使用:

    	@PostMapping("/login")
    	@ApiOperation(value = "用户登录/注册接口")
    	@ApiImplicitParams({
    			@ApiImplicitParam(name = "identifyCode", value = "用户输入的验证码", required = true),
    			@ApiImplicitParam(name = "telNumber", value = "用户手机号", required = true),
    	})
    	public RestResponse login(BaseMsg baseMsg, @NotNull String identifyCode)  {
    		return this.wrap(baseMsgService.login(baseMsg, identifyCode));
    	}
    

    https://blog.csdn.net/oKuZuoZhou/article/details/81024795
    切入点的定义

    http://www.jfinal.com/share/1306
    注解传入数组

    https://blog.csdn.net/piaoranyuji/article/details/89448632
    request

    https://www.iteye.com/blog/elim-1812584
    不适用aop

    https://blog.csdn.net/qq_15071263/article/details/83825132
    参考

  • 相关阅读:
    腾讯加入QQ群,代码生成地址
    jsTree 是一个基于Javascript,支持多浏览器的Tree view jQuery插件。
    PHP Ajax 跨域问题最佳解决方案
    【转载】目前主流过滤XSS的三种技术
    nginx中location、rewrite用法总结
    Tomcat请求头过大
    ssh秘钥分发错误“/usr/bin/ssh-copy-id: ERROR: No identities found”
    ssh分发秘钥时出现错误“Permission denied (publickey,gssapi-keyex,gssapi-with-mic)”
    修改Jenkins用户的密码
    注销/etc/passwd带来的系统登陆不上
  • 原文地址:https://www.cnblogs.com/cashew/p/11357975.html
Copyright © 2011-2022 走看看