spring SSM 工程 使用AOP + 自定义注解 进行参数非空校验

8 篇文章 0 订阅
4 篇文章 0 订阅

如果你是springboot的用户,不用看这篇文章,可以查看并使用 validation 来进行处理,我这里主要为了方便老系统SSM 的一些get请求或者其它等可能对validation 进行支持不太好的,

代码有不少是复制粘贴项目的,可能有一些冗余或者报错,但是相信大家可以解决

 

我的项目是使用 spring 4.3.8 整合的,xml 形式的SSM 单体工程

首先我们定义一个注解,针对了注解了该注解的方法进行切入AOP:

package com.kds2.annotation;

import java.lang.annotation.*;

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CheckBlank {

    String message() default "";
    String name() default "";
}

 

定义切面(注意此处类名不要加Compoent)

package com.kds2.aop;

import com.kds2.annotation.CheckBlank;
import com.kds2.annotation.CountTime;
import com.kds2.exception.ServiceException;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
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.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

/**
*@Description: 接口参数非空校验
*@Author: guanzhou.su,  dont know what is  mean? contact me at QQ:838951396, wechat:13824866769
*@Date: 2020/01/05
**/
@Aspect
public class CheckBlankAop {
    private static Logger logger = Logger.getLogger(CheckBlankAop.class);

    @Before("@annotation(com.kds2.annotation.CheckBlank)")
    public void nullOrEmptyFilter(JoinPoint joinPoint) throws Exception{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //获得参数类型
        final Parameter[] parameters = method.getParameters();
        //参数值
        final Object[] args = joinPoint.getArgs();
        for(int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            Object annotation = parameter.getAnnotation(CheckBlank.class);
            // 获取字段名称
            String name = parameter.getAnnotation(CheckBlank.class).name();
            //含有不为空的注解的参数
            if (null != annotation) {
                if (null == args[i]) {
                    throw new ServiceException(name + "不能为 null");
                }
                if (args[i] instanceof String) {
                    String str = (String) args[i];
                    if(str.trim() == "") throw new ServiceException(name + "不能为空");
                }
            }
        }
    }
}

上面的Parameter为JAVA8的类,需要JAVA8之前的写法需改成以下:

    @Before("@annotation(com.kds2.annotation.CheckBlank)")
    public void nullOrEmptyFilter(JoinPoint joinPoint) throws Exception{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();

        //获得参数
        Object[] args = joinPoint.getArgs();

        // 获取参数注解,此处是一个二维数据,每个方法可以有多个入参,而每个方法又允许多个注解
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        for (Annotation[] annotations : parameterAnnotations) {
            int paramIndex= ArrayUtils.indexOf(parameterAnnotations, annotations);
            for (Annotation annotation : annotations) {
                //获取注解名
                if (annotation instanceof CheckBlank) {
                    String name = ((CheckBlank) annotation).name();
                    Object paramValue = args[paramIndex];
                    if (paramValue instanceof String) {
                        String str = (String) paramValue;
                        if(str.trim() == "") throw new ServiceException(name + "不能为空");
                    }
                }
            }
        }
    }
 

上面的校验中使用了我自己定义的异常,这里你根据自己需要进行更改,不需要的话你自己进行其他额外处理

package com.kds2.exception;

/**
*@Description: 业务相关非系统异常
*@Param: 
*@Author: guanzhou.su,  dont know what is  mean? contact me at QQ:838951396, wechat:13824866769 
*@Date: 2020/1/2
*@return: 
 * 
**/
public class ServiceException extends Exception{
    public ServiceException() {
        super();
    }

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

springmvc 配置文件增加以下代码:

<!-- 如果需要注解到 controller 层,需要额外处理 -->
    <aop:aspectj-autoproxy/>
    <bean id="sysLogAop" class="com.kds2.aop.CheckBlankAop"></bean>

 

controller 代码(需要在方法上加@CheckBlank, 参数上也需要, name 为你这个字段的描述):

@RestController
@RequestMapping("api/nb/")
public class UserInfoController extends BaseController {

    @CheckBlank
    @PostMapping("/get")
    public String getUserInfo(@CheckBlank(name = "用户ID") String userId){
        return userId;
    }
}

 

全局异常的处理,统一捕获业务异常:

package com.kds2.controller.ExceptionHandler;

import com.kds2.exception.ServiceException;
import com.kds2.resp.VoResp;
import org.apache.log4j.Logger;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
*@Description: 统一异常拦截
*@Author: guanzhou.su,  dont know what is  mean? contact me at QQ:838951396, wechat:13824866769 
*@Date: 2020/1/2
**/
@RestControllerAdvice
public class GlobalExceptionHandler {

    public static final int SERVICE_ERROR_CODE = 550;

   /**
   *@Description: 普通业务异常捕获
   *@Param: 
   *@Author: guanzhou.su,  dont know what is  mean? contact me at QQ:838951396, wechat:13824866769 
   *@Date: 2020/1/2
   *@return: 
    * 
   **/
    @ExceptionHandler(ServiceException.class)
    public VoResp serviceException(ServiceException e) {
        e.printStackTrace();
        VoResp resp = new VoResp();
        log.error(e.getMessage(), e);
        resp.setErrorCode(SERVICE_ERROR_CODE);
        resp.setMsg(e.getMessage());
        return resp;
    }
}

返回类:

public class VoResp<T>{
    /*
	 * 返回状态码
	 */
	private Integer errorCode = 0;
	/*
	 * 返回消息
	 */
	private String msg;
	/*
	 * 返回对象
	 */
	private Object obj;

	private T data;

	public VoResp() {}

      // 省略 getter 和setter 大家自行补上
}

 

測試訪問:

字段为空

localhost:8080/hlzqweixin/api/nb/get

返回如陰影部分

 

字段非空,但是没有值

localhost:8080/hlzqweixin/api/nb/get?userId=

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值