如果你是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=