使用SpringMVC作为Controller层进行Web开发时,经常会需要对Controller中的方法进行参数检查。本来SpringMVC自带@Valid和@Validated两个注解可用来检查参数,但只能检查参数是bean的情况,对于参数是String或者Long类型的就不适用了,对此,可以利用Spring的AOP和自定义注解,自己写一个参数校验的功能。
代码示例
注意:本节代码只是一个演示,给出一个可行的思路,并非完整的解决方案。
本项目是一个简单Web项目,使用到了:Spring、SpringMVC、Maven、JDK1.8
自定义注解:
ParameterCheck.java:
import com.example.recordlog.service.ParameterValidator;
import com.example.recordlog.service.impl.NotNullParam;
import java.lang.annotation.*;
/**
* @author liuminglin
* 标注在参数bean上,表示需要对该参数校验
*/
@Inherited
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterCheck {
Class<? extends ParameterValidator> validator() default NotNullParam.class;
}
验证器接口,定义一个参数校验方法
Validator.java:
/**
* @desc: 验证器接口
*/
public interface Validator<T> {
boolean isValid(T input);
}
参数验证器接口
/**
* @author
* @Desc ParameterValidator 参数验证器接口,用的时候实现这个接口就可以了
*/
public interface ParameterValidator<T> extends Validator<T> {
}
默认参数实现类
/**
* @author
* @Desc defaultNotNullParam 默认非空参数实现类
*/
public class NotNullParam implements ParameterValidator<BaseRequest> {
@Override
public boolean isValid(BaseRequest input) {
return input != null;
}
}
参数请求实体类
BaseRequest
import com.alibaba.fastjson.JSONObject;
import java.io.Serializable;
public class BaseRequest implements Serializable {
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
参数验证实现类
import com.example.recordlog.bean.UserInfo;
import com.example.recordlog.service.ParameterValidator;
import org.apache.commons.lang3.StringUtils;
/**
* @author
* @Desc UserRequestValidator 用户参数验证器实现类
*/
public class UserRequestValidator implements ParameterValidator<UserInfo> {
@Override
public boolean isValid(UserInfo request) {
//必传参数
if (request == null
|| StringUtils.isBlank(request.getId())
|| StringUtils.isBlank(request.getUserId())
|| StringUtils.isBlank(request.getUserName())
|| StringUtils.isBlank(request.getPhone())
|| StringUtils.isBlank(request.getHometown())
|| StringUtils.isBlank(request.getEmail())
|| StringUtils.isBlank(request.getAddress())
|| request.getCreatTime() == null
|| request.getModifyDate() == null
) {
return false;
}
if (!request.getUserId().equals("admin")) {
return false;
}
return true;
}
}
切面类
ParamCheckAspect.java:
import com.example.recordlog.anotation.ParameterCheck;
import com.example.recordlog.service.ParameterValidator;
import com.example.recordlog.service.impl.BaseRequest;
import com.example.recordlog.tools.AspectUtil;
import com.example.recordlog.tools.ResponseUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ParamCheckAspect {
/**
* 切入点
*/
@Pointcut("@annotation(com.example.recordlog.anotation.ParameterCheck)")
private void pointcut() {
}
@Around("ParamCheckAspect.pointcut()")
public ResponseUtils around(ProceedingJoinPoint pjp) throws Throwable {
ResponseUtils ret = null;
//获取注解
ParameterCheck annotation = AspectUtil.getAnnotation(pjp, ParameterCheck.class);
if (annotation != null) {
ParameterValidator<BaseRequest> validator = getParamValidator(annotation);
//获取请求参数
BaseRequest requestArgs = AspectUtil.getFirstParamsOfTargetClass(pjp, BaseRequest.class);
if (validator != null && !validator.isValid(requestArgs)) {
ret = ResponseUtils.fail("参数异常");
}
ret = ResponseUtils.success(pjp.proceed());
}
return ret;
}
//获取参数验证器
private ParameterValidator<BaseRequest> getParamValidator(ParameterCheck paramCheckAnnotation) {
ParameterValidator<BaseRequest> validator = null;
Class<? extends ParameterValidator> validatorClass = paramCheckAnnotation.validator();
try {
validator = validatorClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
}
return validator;
}
}
用法
@RequestMapping(value = "/updateInfo", produces = "application/json;charset=utf-8", method = {RequestMethod.POST})
@ParameterCheck(validator = UserRequestValidator.class)
public ResponseUtils updateInfo(@RequestBody UserInfo info) {
UserInfo info1 = (UserInfo) baseDao.select(NameSpaceEnum.USER_MAPPER, "selectByPrimaryKey", Long.parseLong(info.getId()));
int count = userInfoService.updateByPrimaryKeySelective(info);
ResponseUtils responseUtils = ResponseUtils.success(count);
return responseUtils;
}