AOPアスペクト無限再帰検証リクエストパラメータコントローラ

シーンは、基本的なシングル/パッケージタイプの属性パラメータおよび内部パラメータエンティティクラスを満たすために、検証のために提出されたパラメータコントローラで直接Aを書いて、他のプラグインフレームワークに行きませんでした

騒ぎ、コード:

  ValidationAspect

package com.shinedata.aop;

import com.shinedata.Exception.ValidationException;
import com.shinedata.annotation.Validation;
import com.shinedata.annotation.ValidationModel;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.Order;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Pattern;

/**
 * @ClassName ValidationAspect
 * @Author yupanpan
 * @Date 2019/9/29 15:27
 */
@Order(0)
@Aspect
@Component
public class ValidationAspect {

    @Pointcut("execution(* com.shinedata.controller..*(..))")
    public void validation() { }

    @Before("validation()")
    public void validateParam(JoinPoint point) throws NoSuchMethodException, InvocationTargetException,
            IllegalAccessException {
        Signature signature = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        //所有参数名称的字符串数组
        String[] parameterNames = methodSignature.getParameterNames();
        //参数值
        Object[] args = point.getArgs();
        //获取参数注解 //参数注解,1维是参数,2维是注解
        Annotation[][] parameterAnnotations = methodSignature.getMethod().getParameterAnnotations();
        for (int i = 0; i < parameterAnnotations.length; i++) {
            Annotation[] paramAnn = parameterAnnotations[i];
            String parameterName = parameterNames[i];
            //参数没有注解,直接下一个参数
            if(paramAnn.length == 0){
                continue;
            }
            for (Annotation annotation : paramAnn) {
                Object param = args[i];
                //这里判断当前注解是否为Validation.class
                if(annotation.annotationType().equals(Validation.class)){
                    validateParamValue(param,annotation,parameterName);
                }else if(annotation.annotationType().equals(ValidationModel.class)){
                    validateParamModelValue(param);
                }
            }
        }
    }

    private void validateParamModelValue(Object param) throws InvocationTargetException, IllegalAccessException,
            NoSuchMethodException {
        //遍历属性字段,获取属性上的注解值
        Field[] fields = param.getClass().getDeclaredFields();
        if(fields!=null&&fields.length>0){
            for (Field field : fields) {
                Annotation[] annotations = field.getAnnotations();
                if(annotations!=null&&annotations.length>0){
                    for (Annotation classFieldAnn : annotations) {
                            //获取属性值
                            String fieldName=field.getName();
                            Method method=param.getClass().getMethod("get"+ fieldName.substring(0,1).toUpperCase()+fieldName.substring(1));
                            Object classFiledValue = method.invoke(param);
                        if(classFieldAnn.annotationType().equals(Validation.class)) {
                            validateParamValue(classFiledValue, classFieldAnn, fieldName);
                        }else if(classFieldAnn.annotationType().equals(ValidationModel.class)){
                            validateParamModelValue(classFiledValue);
                        }
                    }
                }
            }
        }
    }

    private void validateParamValue(Object param,Annotation annotation,String parameterName){
        Validation validation=(Validation)annotation;
        if(validation.notNull()&&param==null){
            throw new ValidationException(StringUtils.isBlank(validation.message())?parameterName+"不能为空":validation.message());
        }
        String p = param.toString();
        if(StringUtils.isNotBlank(validation.min())){
            if(Long.valueOf(validation.min())>(Long.valueOf(p))){
                throw new ValidationException(parameterName+"参数值错误,最小值"+validation.min());
            }
        }
        if(StringUtils.isNotBlank(validation.max())){
            if(Long.valueOf(validation.max())<(Long.valueOf(p))){
                throw new ValidationException(parameterName+"参数值错误,最大值"+validation.max());
            }
        }
        if(StringUtils.isNotBlank(validation.pattern())){
            boolean isMatch = Pattern.matches(validation.pattern(), p);
            if(!isMatch){
                throw new ValidationException(parameterName+"参数格式错误");
            }
        }
    }

}

上記セクションのコア。

カスタム例外にValidationException

package com.shinedata.Exception;

/**
 * @ClassName ValidationException
 * @Author yupanpan
 * @Date 2019/9/29 16:08
 */
public class ValidationException extends Exception {

    private static final long serialVersionUID = -7328486927134375179L;

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

    public ValidationException(String message,Exception e) {
        super(message,e);
    }
}
@ControllerAdvice 增强Controller捕获异常给前端返回错误信息

グローバル例外ハンドラGlobalExceptionHandler

package com.shinedata.Exception;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONException;
import com.shinedata.util.Result;

/**
 * 全局异常处理
 * @ClassName ValidationAspect
 * @Author yupanpan
 * @Date 2019/9/29 15:27
 */
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
	
	
	private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	
	@ExceptionHandler(ValidationException.class)
	public Result exceptionHandler(ValidationException e){
		Map<String, Object> map = new HashMap<>();
		map.put("flag", 600);
		Result result = Result.getResult(600, e.getMessage(), map);
		return result;
	}
	
	
}

 

2つの単純なカスタム注釈

エンティティクラスを要求するためのValidationModel注釈パラメータ

package com.shinedata.annotation;


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

/**
 * @ClassName ValidateParams
 * @Author yupanpan
 * @Date 2019/9/29 14:44
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE,ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidationModel {

    /**
     * A list of {@link Validation}s available to the param operation.
     */
    //Validation[] value();
}

非エンティティクラスを要求するための検証注釈パラメータ

package com.shinedata.annotation;


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

/**
 * @ClassName ValidateParams
 * @Author yupanpan
 * @Date 2019/9/29 14:44
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE,ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Validation {

    /**
     * 验证失败返回描述
     * @return
     */
    String message() default "";

    /**
     *最大值 数字字符串
     * @return
     */
    String max() default "";
    /**
     *最小值
     * @return
     */
    String min() default "";
    /**
     *正则验证
     * @return
     */
    String pattern() default "";
    /**
     *是否必填,默认是
     * @return
     */
    boolean notNull() default true;


}

 

例えば、使用、

@ValidationModel

 

公開された288元の記事 ウォン称賛88 ビュー430 000 +

おすすめ

転載: blog.csdn.net/ypp91zr/article/details/101703848