1. 简介 在java开发中,经常见到许多通过注解@Annotation实现功能的优秀代码,尤其在接触spring之后,对注解更是一发不可收拾,这里将向读者介绍一种范围定界方法。需要说明的是,这种定界方法不能独立于世,而必须结合Validation-api-*.jar公共包一起使用。这里以定界一个变量privateString agentId;
取值范围(1,3) 为例来说明。
2. 创建Annotation 在eclipse上选中某个指定的package,右键 new ,选择Annotation,这里创建的Annotation的名字叫做@IntRange,其代码如下
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import javax.validation.Constraint;
import javax.validation.Payload;
import com.*.constrait.validator.IntRangeValidator;
/**
*
* @author ***
* @see 用于判定指定类中的某个域是否在规定区间之内
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = IntRangeValidator.class)
public @interface IntRange { String message() default "{com.*.validation.constraints.IntRange.message}";
Class>[] groups() default { };
Class extends Payload>[] payload() default { };
int min() default 0;
int max() default Integer.MAX_VALUE;
}
代码中的@Target 用于指定该注解的应用范围,此注解应用于 方法、域、构造函数 、入参四个区域;@Retention指定应用时间,这里是RUNTIME;@Constraint指明具体实现的类,即IntRangeValidator.java类
代码中定义了两个函数 int min(); 和 int max(); 两个函数都有各自的默认值。
Annotation可以认为是一个接口,其中只是简单定义了要实现哪些功能,具体的实现步骤则交由其他指定的类(这里专指IntRangeValidator)去处理。
3. 具体实现 上面已经指出,@Annotation只是一个类似于接口的类,具体的实现由其他类完成,这里将介绍具体实现,代码如下:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.*.constrait.constrains.IntRange;
public class IntRangeValidator implements ConstraintValidator { private int min;
private int max;
@Override
public void initialize(IntRange arg0) {
this.min = arg0.min();
this.max = arg0.max();
} @Override
public boolean isValid(String value, ConstraintValidatorContext arg1) {if((null == value) || 0 == value.length()) {
return false;
}try {
int integer = Integer.valueOf(value);
//System.out.println("++++++ the value is " + integer+ " +++++++");
return (integer > this.min) && (integer < this.max);
}catch(NumberFormatException e) {
//System.out.println("---there is a exception , " + e.toString());
return false;
} }}
该函数实现了ConstraintValidator接口,该接口为泛型接口,第一个参数IntRange为上文中的Annotation,其他代码也比较容易理解,此处不做介绍。
4.使用方法 【使用 ConstraintValidator 接口及BindingResult实现注解定义参数范围】假设定义了一个类Mytest01,其中有一个变量private String agentId; ,则注解的方式如下
public class BasicInfo {}public class Mytest01 extends{@IntRange(min=1,max=3)
private String agentId;
}
代码@IntRange()中的min和max分别调用了@IntRange中的两个函数。
该注解一般应用于对外接口,和@RequestBody、@Valid、@BindingResult一起使用,代码如下
import javax.validation.Valid;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(value="https://www.it610.com/cct")
public class CcgmsController { @PostConstruct
public void init() {
System.out.println("----------------------------------");
}
@RequestMapping(value="https://www.it610.com/agent", headers = "Accept=application/json", method = RequestMethod.POST)
public @ResponseBody ResultInfo agentAction(@RequestBody @Valid Mytest01
mytest,BindingResult result, HttpServletRequest request) {if(result.hasErrors()) {
List list = result.getFieldErrors();
for(FieldError error:list) {
System.out.println(error.getObjectName()+"." + error.getField() + " failed;
cause by : "+ error.getDefaultMessage());
}
}System.out.println("++++++++++++++++++++++++++++");
return new ResultInfo("0");
}
}public class ResultInfo { private String result;
ResultInfo(){ }
public ResultInfo(String result){
this.result = result;
}
..........//省略get/set方法
}
当mytest入参有问题时,则将执行如下代码if(result.hasErrors){}
上述使用是结合BindingResult的,而实际使用中又不一定会用到它,如果项目中不用BindingResult,那又应该如何实现呢? 其实Validate已经提供了类似的方法,代码如下,在使用的地方显式的调用一下Validate.checkInfo() 方法来检测注解
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import com.***.BasicInfo;
public class Validate {
private static javax.validation.Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();
public static boolean checkInfo(BasicInfo basicInfo) {if(null == basicInfo) {
System.out.println("[ccgms]: basicInfo is null");
return false;
}Set> sets =Validate.VALIDATOR.validate(basicInfo);
if(!sets.isEmpty()) {
System.out.println("[ccgms-validate] : there is error message" );
for(ConstraintViolation set:sets) {
//参数所在类的名称
String className = set.getRootBeanClass().getSimpleName();
//参数所在类的具体域的名称
String path = set.getPropertyPath().toString();
//定义的注解中的默认message
String message = set.getMessage();
System.out.println("[className]="+className+" ;
[path]=" + path+" ;
[message]=" + message );
}
return false;
}return true;
}
}
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)