1. 程式人生 > >通過AOP切入註解的方式對介面引數進行非空判斷

通過AOP切入註解的方式對介面引數進行非空判斷

文章目錄

通過AOP切入註解的方式對介面引數進行非空判斷


1、建立註解
package com.zyfycs.college.core.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author Created by 譚健 on 2018/11/2 0002. 星期五. 9:47.
 * © All Rights Reserved.
 */


@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HandleParams {


    /**
     * 不需要檢驗的引數的名稱
     * 預設情況下,會檢查該介面的所有引數值
     */
    String[] excludeParams() default {};


    /**
     * notNull
     * notBlank
     * 兩個只會處理一個,notBlank 的優先順序更高,
     * 如果notBlank 為 true 則不進行 notNull 邏輯處理,因為 notNull 是 notBlank 的子內容
     * 如果只使用 notNull 判斷,則應該設定 notBlank 為 false ,notNull 為true
     */
    boolean notNull() default false;

    boolean notBlank() default true;
}

2、建立切入點

package com.zyfycs.college.core.aop;

import com.google.common.collect.Lists;
import com.zyfycs.college.core.aop.annotation.HandleParams;
import com.zyfycs.college.exception.runtime.ParamBlankException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Created by 譚健 on 2018/11/2 0002. 星期五. 9:45.
 * © All Rights Reserved.
 */


@Slf4j
@Component
@Aspect
public class AspectParamCheck {


    @Around("@annotation(com.zyfycs.college.core.aop.annotation.HandleParams)")
    public Object paramCheck(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        String[] parameterNames = signature.getParameterNames();
        Object[] args = point.getArgs();
        Class<?>[] parameterTypes = signature.getParameterTypes();
        HandleParams handleParams = signature.getMethod().getAnnotation(HandleParams.class);
        String[] excludeParams = handleParams.excludeParams();
        List<String> excludeParamList = Lists.newArrayList(excludeParams);
        String location = point.getTarget().toString() + "." + signature.getMethod().getName();
        for (int i = 0; i < args.length; i++) {
            if (handleParams.notBlank()) {
                notBlank(location, excludeParamList, parameterNames[i], args[i], parameterTypes[i].getName());
            } else if (handleParams.notNull()) {
                notNull(location, excludeParamList, parameterNames[i], args[i], parameterTypes[i].getName());
            }
        }
        return point.proceed();
    }


    private void notNull(String location, List<String> excludeParamList, String paramName, Object value, String paramType) {
        // 如果該引數不在排除範圍內,則進行校驗
        if (!excludeParamList.contains(paramName)) {
            if (value == null) {
                throw new ParamBlankException(location + " Error : [" + paramName + "] is Null ,Type is [" + paramType + "]");
            }
        }
    }

    private void notBlank(String location, List<String> excludeParamList, String paramName, Object value, String paramType) {
        // 如果該引數不在排除範圍內,則進行校驗
        if (!excludeParamList.contains(paramName)) {
            if (value == null || StringUtils.isBlank(value.toString())) {
                throw new ParamBlankException(location + " Error : [" + paramName + "] is Blank ,Type is [" + paramType + "]");
            }
        }
    }
}


3、應用註解

只需要在有引數並且需要做非空判斷的介面方法上打上 @HandleParams 註解就會自動檢查了


    @HandleParams
    @GetMapping("/request")
    public ApiResponse request(BigDecimal amount, Long bankCardId,String authCode,String code) {}

4、註解響應

當註解工作後,會丟擲ParamBlankException 異常


package com.zyfycs.college.exception.runtime;

import lombok.Getter;

/**
 * @author Created by 譚健 on 2018/11/2 0002. 星期五. 10:02.
 * © All Rights Reserved.
 */

@Getter
public class ParamBlankException extends RuntimeException {

    public ParamBlankException() {
    }

    public ParamBlankException(String message) {
        super(message);
    }
}


異常丟擲後,由全域性異常處理器處理,通過Rest 方式返回給前端
並且在控制檯列印具體的錯誤資訊

    @ExceptionHandler(ParamBlankException.class)
    @ResponseBody
    public ApiResponse resolveException(HttpServletRequest request,ParamBlankException e){
        log.error(e.getMessage());
        return new ApiResponse(ErrorEnum.PARAM_BLANK);
    }