基于注解的校验器,本文使用的是拦截器,并将拦截器交给nutz的ioc容器进行管理。思路是在前台发过来的请求,在被指定的函数接收参数前,会先被拦截,在拦截器中获取方法的参数,及需要校验的字段,校验类型,并将校验结果放到一个对象中,并将对象赋值给函数参数。本例子中前段只会传递一个参数json,所有需要的参数都封装在了json中,json格式如{id:1,name:"cai10"}
主要用到的类有以下几个:
1、首先是自定义注解:ValidationAnnotation
@Target(value={ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidationAnnotation {
/**
*
* @Title key需要校验的字段类型,如required等
* @Description
* @author Administrator
* @param
* @date 2015-5-14
* @return String
*/
ValidationType validationType() default ValidationType.REQUIRED;
/**
*
* @Title value
* @Description 校验的字段
* @author Administrator
* @param
* @date 2015-5-14
* @return String[]
*/
String[] fieldValues() default {};
}
2、自定义校验类型:ValidationType
public enum ValidationType {
/*必填*/
REQUIRED
//可以根据业务需要添加一些其他类型的校验
}
3、错误信息汇总类,存储校验失败的信息:Errors
/**
* 验证错误信息汇总类
*
* @author QinerG(QinerG@gmail.com)
*/
public class Errors {
/*
* 存放错误信息的 map
*/
private Map<String, String> errorMap = new TreeMap<String, String>();
/**
* @return 是否存在验证错误
*/
public boolean hasError() {
return errorMap.size() > 0;
}
/**
* @return 返回存在错误的总数
*/
public int errorCount() {
return errorMap.size();
}
/**
* 增加一个错误信息
*
* @param fieldName
* 存在错误的字段名
* @param errorMessage
* 错误的详细信息
*/
public void add(String fieldName, String errorMessage) {
errorMap.put(fieldName, errorMessage);
}
/**
* 返回错误信息列表
* @return
*/
public Collection<String> getErrorsList() {
return errorMap.values();
}
/**
* 返回详细的错误信息列表,含验证错误的字段名和提示语
* @return
*/
public Map<String, String> getErrorsMap() {
return errorMap;
}
}
4、自定义的拦截器,并继承nutz的AbstractMethodInterceptor:ValidationInterceptor
/**
* 基于注解的验证
* @author Administrator
*
* 2015-5-14
*/
@IocBean//注意必须将此拦截器交给ioc管理
public class ValidationInterceptor extends AbstractMethodInterceptor{
@Override
public boolean beforeInvoke(Object obj, Method method, Object... args) {
//定义 第一个参数为json, 第二个参数为Errors对象
if(args.length ==2){
String json = (String) args[0];
NutMap map = Json.fromJson(NutMap.class, json);
ValidationAnnotation anno = method.getAnnotation(ValidationAnnotation.class);
ValidationType validator_type = anno.validationType();
String[] values = anno.fieldValues();
//如果是校验必填项
if(ValidationType.REQUIRED.equals(validator_type)){
//判断每个字段是否都存在于数组values中
Errors es = null;
for(String val:values){
if(!map.containsKey(val)){
args[2] = es= new Errors();
es.add("required_string", "param ["+val+"] is requred, please check!......");
break;
}
}
}
}
return super.beforeInvoke(obj, method, args);
}
}
5、使用校验器的函数如下:
@Aop("validationInterceptor")
public void saveSupplierInfo(@Param("json")String json, Errors error) throws IOException{
try {
if(error.hasError()){
result.setSuccessData(error.getErrorsList().toString());
}else{
boolean flag = supplierService.saveSupplierInfo(json);
result.setSuccessData(flag);
}
} catch (Exception e) {
e.printStackTrace();
result.setExceptionData(e.getMessage());
log.error(e.getMessage());
}
HttpKit.responseJson(result, getResponse());
}
可能有些设计不合理,望相互学习指教