为了工作也为了更加深入了解掌握java注解的使用,决定自定义注解来实现数据验证。
最开始也考虑使用jsr-303规范来实现功能,但是对于开发人员来说比较累,因为要去实体类对象中添加验证字段注解,而且要进入到method当中。上一篇写的springmvc数据验证就是用jsr-303规范实现的。今天自定义了一下。也挺不错。
自定义注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Validator {
public String[] fields();
public String bean() default "";
}
controller:
@RequestMapping(value="index3.do",method=RequestMethod.POST)
@ResponseBody
@Validator(fields={"username"+ValidatorConstant.NOT_NULL,"age"+ValidatorConstant.NOT_NULL},bean="myValidatorService")
public JSONObject index3(User user,HttpServletRequest request) {
JSONObject ret=new JSONObject();
ret.put("cuixuefeng", "25岁");
return ret;
}
其中fields是对应属性字段进行设置,bean是自定义Validator接口实现。
过滤器:
public class MyHandler extends HandlerInterceptorAdapter implements ApplicationContextAware{
private static ApplicationContext ac;
/**
* 请求执行前拦截
* @param request 请求对象
* @param response 响应对象
* @param
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
HandlerMethod method=(HandlerMethod)handler;
Class<?> clazz=method.getBean().getClass();
String method_name=method.getMethod().getName();
return ValidatorUtil.getMethodInfo(clazz, method_name,request,ac);
}
/* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
// TODO Auto-generated method stub
ac=arg0;
}
}
注解处理类:
public class ValidatorUtil {
public static boolean getMethodInfo(Class<?> clazz,String method_name,HttpServletRequest request,ApplicationContext ac){
Method[] methods = clazz.getDeclaredMethods();
for(Method method :methods){
if(method.getName().equals(method_name)){
if(method.isAnnotationPresent(Validator.class)){
Validator validator = method.getAnnotation(Validator.class);
String[] fields=validator.fields();
String bean=validator.bean();
if(!verify(fields, request)){
return false;
}else{
if(!"".equals(bean)){
return ((IValidatorService)ac.getBean(bean)).verify(request);
}
}
}
}
}
return true;
}
public static boolean verify(String[] fields,HttpServletRequest request) {
for(String field:fields){
String[] params=field.split(":");
if(!verify(params[1], request.getParameter(params[0]))){
return false;
}
}
return true;
}
public static boolean verify(String type,String param) {
if(type.equals(ValidatorConstant.NOT_NULL.substring(1))){ //校验非空
if(param==null||"".equals(param)){
return false;
}
}else if (type.equals(ValidatorConstant.NOT_ZERO.substring(1))) {//校验为0
if(param.equals("0")){
return false;
}
}else if (type.equals(ValidatorConstant.PHONE_NUM.substring(1))) {//校验手机号码11位
if(!(param.length()==11)){
return false;
}
}else if (type.equals(ValidatorConstant.ID_CARD.substring(1))) {//校验身份证合法
return IdCardUtil.verify(param);
}
return true;
}
}
注解类型参数:
public class ValidatorConstant {
/**
* 非空
*/
public static final String NOT_NULL=":NOT_NULL";
/**
* 不等于0
*/
public static final String NOT_ZERO=":NOT_ZERO";
/**
* 日期格式
*/
public static final String DATE_FORMAT=":DATE_FORMAT";
/**
* email格式
*/
public static final String EMAIL_FORMAT=":EMAIL_FORMAT";
/**
* 身份证校验
*/
public static final String ID_CARD=":ID_CARD";
/**
* 字符长度
*/
public static final String STR_LENGTH=":STR_LENGTH";
/**
* 正则表达式
*/
public static final String REG_EXP=":REG_EXP";
/**
* 手机号码校验
*/
public static final String PHONE_NUM=":PHONE_NUM";
}
以上实现其实是两个功能并列的关系,注解中接收两个参数:fields和bean,通过标签写入的fields可以实现基本校验,复杂的校验需要重新实现service进行实现。
接口:
public interface IValidatorService {
/**
* 校验(复杂校验方法)
* @param request 请求参数
* @return boolean 通过校验返回true否则返回false
*/
public boolean verify(HttpServletRequest request);
}