注解方式实现输入参数验证
场景:接口调用时,对输入参数进行校验是否为空,格式是否正确等等。
关键词:AOP,字段注解,@Validated,@Valid,@RequestBody,BindingResult,AOP配置
代码:
Controller
@Validated @Controller @RequestMapping("/qh") public class QhController { private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(QhController.class); @Resource private QianHaiQueryService qhQueryService; @Resource private QianHaiBatchService qhBatchService; // 接口:风险度提示 @RequestMapping(path = "/rskdoo", method = {RequestMethod.POST}) @ResponseBody public ResponseResult<BusiData<RskdooResponseRecord>> rskdoo(HttpServletRequest request, @Size(max = 50, message = "最多不能多于50条数据") @Valid @RequestBody List<RskdooRequestRecord> record, BindingResult result) { ResponseResult<BusiData<RskdooResponseRecord>> responseResult = new ResponseResult<>(); record = setRecords(record, request); BusiData<RskdooResponseRecord> entity = qhQueryService.queryRskdoo(record); responseResult.setData(entity); responseResult.setRet(true); return responseResult; }
请求实体
public class RskdooRequestRecord extends RequestRecord{ @NotBlank(message = "证件号码不能为空") @CheckLength(max = 64, message = "证件号码不能大于64位") private String idNo; @NotBlank(message = "证件类型不能为空") @Pattern(regexp = "^([0-9]|X)$", message = "证件类型的值错误") private String idType; @NotBlank(message = "主体名称不能为空") @CheckLength(max = 128, message = "主体名称不能大于128位") private String name; @NotBlank(message = "查询原因不能为空") @Pattern(regexp = "^(01|02|03|04|05|99)$", message = "查询原因的值错误") private String reasonCode;
AOP
public class ValidateResultAop { /** * @param joinPoint * @return * @throws Throwable */ public Object around(ProceedingJoinPoint joinPoint) throws Throwable { BindingResult bindingResult = null; ResponseResult<?> result = new ResponseResult<>(); for (Object arg : joinPoint.getArgs()) { if (arg instanceof BindingResult) { bindingResult = (BindingResult) arg; } } if (bindingResult != null) { List<ObjectError> errors = bindingResult.getAllErrors(); if (errors.size() > 0) { StringBuilder msg = new StringBuilder(); for (ObjectError error : errors) { if (StringUtils.isEmpty(msg)) msg.append(error.getDefaultMessage()); else msg.append(",").append(error.getDefaultMessage()); } msg.append("。"); result.setErrorMsg(msg.toString()); return result; } } Object obj; try { obj = joinPoint.proceed(); } catch (ConstraintViolationException e) { Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations(); StringBuilder msg = new StringBuilder(); for (ConstraintViolation<?> constraintViolation : constraintViolations) if (StringUtils.isEmpty(msg)) msg.append(constraintViolation.getMessage()); else msg.append(",").append(constraintViolation.getMessage()); msg.append("。"); result.setErrorMsg(msg.toString()); return result; } return obj; } }
AOP配置 ApplicationContext.xml
<!-- 系统服务组件的切面Bean --> <!--所有请求的初始化动作 --> <bean id="accessLogAop" class="com.pingan.credit.aop.AccessLogAop"/> <bean id="validateResultAop" class="com.pingan.credit.aop.ValidateResultAop"/> <bean id="queryHistoryAop" class="com.pingan.credit.aop.QueryHistoryAop"/> <!-- AOP配置 --> <aop:config> <aop:aspect id="controllerAspect2" ref="validateResultAop" order="2"> <aop:pointcut id="validateResultAopPC" expression="execution(* com.pingan.credit.controller.QhController.*(..)))"/> <aop:around method="around" pointcut-ref="validateResultAopPC"/> </aop:aspect> <aop:aspect id="controllerAspect3" ref="queryHistoryAop" order="1"> <aop:pointcut id="queryHistoryAopPC" expression="execution(* com.pingan.credit.controller.QhController.totalpdf(..)))"/> <aop:around method="around" pointcut-ref="queryHistoryAopPC"/> </aop:aspect> <aop:aspect id="controllerAspect4" ref="accessLogAop" order="0"> <aop:pointcut id="accessLogAopPC" expression="execution(* com.pingan.credit.controller.*Controller.*(..)))"/> <aop:around method="around" pointcut-ref="accessLogAopPC"/> <aop:before method="before" pointcut="execution(* com.pingan.credit.controller.*Controller.*(..))) and args(..)"/> </aop:aspect> </aop:config>