@ResponseBody
@RequestMapping(value = "add", method = )
public ResponseModel add(@Valid User user, BindingResult br, HttpServletResponse response) {
if(()) {
//将所有的校验错误封装成一个带<br>换行的字符串返回给前端页面进行展示。
return (getErrorsSplitNewLine(br));
}
(user);
return ("保存用户成功");
}
如上面代码所示,我们一般做表单提交数据校验的时候一般使用@Valid对 Bean对象进行校验,而要使用@Valid对对象进行校验需要引入实现JSR303标准的HibernateValidator实现,如下所示:
<!-- JSR303 Validator定义 -->
<bean class="">
<property name="providerClass" value=""/>
<!-- 如果不加下面配置, 默认使用classpath下的 -->
<property name="validationMessageSource" ref="messageSource"/>
</bean>
而上例中add方法的 BindingResult参数对象会绑定校验的结果。所以要求BindingResult对象参数要紧跟在@Valid的对象参数后面,然后代码中通过判定是否存在校验错误。而代码中通过判断是否存在校验错误,来决定是调回表单页进行重新录入还是继续执行业务逻辑。如上例所示,通过if...else...来判断,
if(()) {
} else {
}
所以这种代码逻辑就散布在很多Controller里面,丑陋无比。所以本文就使用aop方式来解决这个问题。
@Aspect
public class ParamValidAspect {
@Around("execution(* .*.*(..)) && args(..,bindingResult)")
public Object validateParam(ProceedingJoinPoint pjp, BindingResult bindingResult) throws Throwable {
Object retVal;
("进入AOP-ParamValidAspect-validateParam进行参数有效性校验....");
if (()) {
String errorInfo = getErrorsSplitNewLine(bindingResult);
("AOP-ParamValidAspect-validateParam进行参数校验出错, 出错信息如下:{}", errorInfo);
retVal = (errorInfo);
} else {
//执行目标方法
retVal = ();
}
return retVal;
}
/*
* 此校验错误信息转化为字符,多个错误信息通过参数[splitChars]进行分隔
*/
private String getErrors(BindingResult br, String splitChars) {
if(splitChars == null) {
splitChars = "";
}
StringBuilder result = new StringBuilder();
List<ObjectError> errors = ();
for (ObjectError vError : errors) {
(());
(splitChars);
}
if(() > 0) {
(() - (), ());
}
return ();
}
/*
* 此校验错误信息转化为字符,多个错误信息通过<br>进行分隔
*/
private String getErrorsSplitNewLine(BindingResult br) {
return getErrors(br, "<br>");
}
}
@Around("execution(* .*.*(..)) && args(..,bindingResult)")
使用切点符合运算,表示切入 ...controller的包以及子包,并且方法的最后一个参数为bindingResult,并将实例直接传递给validateParam方法。
并在SpringMVC中加入如下配置:
<!-- true表示使用cglib代理技术,false表示使用jdk代理技术 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean class=""/>
不使用@Component,的原因已经在上一篇博客文章中说过了:
Spring与SpringMVC是2个不同的父子容器, @Aspect如果被spring容器加载的话,而@Controller注解的这些类的实例化以及注入却是由SpringMVC来完成。 @Aspect如果被spring容器加载的时候,可能Spring MVC容器还未初始化, Controller类还未初始化,所以无法正常织入。。