目录
1. 概述
2. 基于AOP在执行convert方法前进行参数校验
3. 定义参数校验定义切面类和切点
4. 参考链接
1. 概述
可以参考以前做过的项目mwp模块中的查询接口,json转ReqBean时根据reqbean中的校验注解进行参数校验
在基于springboot项目时,可以借助于springboot + validator在controller层实现请求参数的自动校验功能。如下controller类中的请求方法:
/**
* 在controller层,自动实现接口参数校验功能
*/
@RequestMapping(method = {RequestMethod.POST}, value = "/personDetailInfoQuery")
public RspBean<R> npfList(@RequestBody @Validated ReqBean<PersonReqBean> reqBean, HttpServletRequest request) throws Exception {
PageUtils page = service.queryPage(reqBean);
RspBean<R> rspBean = new RspBean<>();
rspBean.setMsgBody(R.ok().put("page", page));
rspBean.setMsgHead(MsgHead.defaultMsgHeaderInstance());
return rspBean;
}
在实际项目中,遇到先将请求参数json接收,然后在后面逻辑转为不同reqBean时进行参数校验,这样就需要手动实现上面的校验逻辑,可借助于如下工具类,实现参数校验
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
/**
* hibernate-validator校验工具类
* 参考文档:http://docs.jboss.org/hibernate/validator/5.4/reference/en-US/html_single/
*/
public class ValidatorUtils {
private static Validator validator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
/**
* 校验对象
* @param object 待校验对象
* @param groups 待校验的组
* @throws RRException 校验不通过,则报RRException异常
*/
public static void validateEntity(Object object, Class<?>... groups)
throws RRException {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
ConstraintViolation<Object> constraint = (ConstraintViolation<Object>)constraintViolations.iterator().next();
throw new RRException(constraint.getMessage());
}
}
}
2. 基于AOP在执行convert方法前进行参数校验
刚开始想在抽象类中的convert()方法做为切点的,但是最后没有成功,AOP对抽象类、抽象方法加切点有特殊要求,以后有时间了再研究。因此就临时选择了另外一种途径。如下抽象类:
public abstract class AbstractQueryService<M extends BaseMapper<T>, T, REQ extends BaseBean> extends ServiceImpl<M,T> implements QueryService {
public PageUtils queryPage(String rawMsg) {
return doQueryPage(convert(rawMsg));
}
/**
* 查询数据
* @param reqBean
* @return
*/
protected PageUtils doQueryPage(ReqBean<REQ> reqBean) {
PageUtils pageUtils = new PageUtils(page);
return pageUtils;
}
/**
* 请求报文转为 reqBean,并校验查询参数是否满足
* @param rawMsg
* @return
*/
public abstract ReqBean<REQ> convert(String rawMsg);
}
如下抽象类的具体实现类:
public class MwpServiceImpl extends AbstractQueryService<ABCDao, ABCEntity, ABCReqBean> {
@Override
public ReqBean<ABCReqBean> convert(String rawMsg) {
ReqBean<ABCReqBean> reqBean = JSONObject.toJavaObject(JSONObject.parseObject(rawMsg), new ReqBean<>().getClass());
reqBean.setMsgBody(JSONObject.toJavaObject(JSONObject.parseObject(rawMsg).getJSONObject("msgBody"), ABCReqBean.class));
return reqBean;
}
}
3. 定义参数校验定义切面类和切点
/**
* 参数校验切面
*/
@Slf4j
@Aspect
@Configuration
public class ParamValidatorAspect {
@Pointcut("execution(* com.xxx.service.QueryService.queryPage(java.lang.String))")
public void validateParam() {
log.info("Pointcut validateParam");
}
/**
* 校验查询参数
*/
@Before("validateParam()")
public void doBefore(JoinPoint pjp) throws Throwable {
Object[] paramValues = pjp.getArgs();
String type = JSONObject.parseObject(String.valueOf(paramValues[0])).getJSONObject(MSG_HEAD).getString(MSG_HEAD_TYPE);
ReqRouterUtil.isAvailableService(type);
Class<?> parameterizedTypeClass = Class.forName((((ParameterizedType)QueryService.queryServerMap.get(type).getClass().getDeclaredMethod(CONVERT_METHOD_NAME, String.class).getGenericReturnType()).getActualTypeArguments()[0]).getTypeName());
String msgBody = JSONObject.parseObject(String.valueOf(paramValues[0])).getString(MSG_BODY);
ObjectMapper mapper = new ObjectMapper();
ValidatorUtils.validateEntity(mapper.readValue(msgBody, parameterizedTypeClass));
log.info("param validate successful");
}
}
/**
* 切点类,进入下一步前,对raw转换为reqbean时做参数校验
*/
@Service("QueryService")
public class MwpQueryService {
public PageUtils queryPage(String rawMsg) {
ReqBean reqBean = JSONObject.toJavaObject(JSONObject.parseObject(rawMsg), new ReqBean<>().getClass());
return QueryService.queryServerMap.get(reqBean.getMsgHead().getType()).queryPage(rawMsg);
}
}
4. 参考链接
获取(泛型)方法返回类型 https://blog.csdn.net/doctor_who2004/article/details/101780509
https://blog.csdn.net/qq_35387940/article/details/106232146
https://blog.csdn.net/qq_28033239/article/details/86740861
https://www.jb51.net/article/110461.htm
https://blog.csdn.net/qq_18769269/article/details/80841734
https://blog.csdn.net/weixin_45627031/article/details/107567577