如何自定义注解?都需要写啥?以下是自己写的残例,有问题,求帮助!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何自定义注解?都需要写啥?以下是自己写的残例,有问题,求帮助!相关的知识,希望对你有一定的参考价值。
下面是我查资料写的,但是有报错,不知道哪里错了,而且不懂如何让自己写这个注解有效使用。
现在把例子送上,希望大神帮我分析一下,帮我梳理一下过程,谢谢..
这是写的解析注解的类(仿照网上写的,不知道什么用)↓↓↓。
import java.lang.reflect.Field;
/**
* 解析注解
* @author xhw
*/
public class ValidateServiceRegularUtil
private static RegularUtil ru;
public ValidateServiceRegularUtil()
super();
//解析的入口
public static void valid(Object object) throws Exception
Class<? extends Object> clazz=object.getClass();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields)
field.setAccessible(true);
validate(field,object);
field.setAccessible(false);
public static void validate(Field field,Object object) throws Exception
Object value;
//获取对象的成员的注解信息
ru=ru.getAnnotation(RegularUtil.class);---------(这句话报错了,为什么呢?)***
if(!ru.regularCardNo(value.toString()))
if(RegularUtil.regularCardNo(value.toString()))
throw new Exception(value+"长度不合法");
这是自定义的注解↓↓↓↓
// import 略
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface cardNoLength
boolean cardNoLength() default true;
这是验证类↓↓
public class RegularUtil
public static boolean regularCardNo(String str)
Pattern pat = null;
boolean rs=false;
String regE;
try
pat = Pattern.compile("^(\\d16|\\d19)$");
Matcher m = pat.matcher(str);
rs = m.find();
catch (Exception e)
e.printStackTrace();
return rs;
错误哪行获取注解信息粘贴错了: 程序里是这样写的
ru=field.getAnnotation(RegularUtil.class);
提示:
Bound mismatch: The generic method getAnnotation(Class<T>) of type AnnotatedElement is not applicable for the arguments (Class<RegularUtil>). The
inferred type RegularUtil is not a valid substitute for the bounded parameter <T extends Annotation>
发现ru=field.getAnnotation(Class<T> class);
参数不能是定义的实体类 应该是注解类 结合你的例子就是RegularUtil.class东东要换成注解类cardNoLength
.class就搞定 参考技术A 这个主要是要认真呢看
JAVA里自定义注解来进行数据验证
API开发中经常会遇到一些对请求数据进行验证的情况,这时候如果使用注解就有两个好处,一是验证逻辑和业务逻辑分离,代码清晰,二是验证逻辑可以轻松复用,只需要在要验证的地方加上注解就可以。
Java提供了一些基本的验证注解,比如@NotNull
、@Size
,但是更多情况下需要自定义验证逻辑,这时候就可以自己实现一个验证注解,方法很简单,仅需要两个东西:
- 一个自定义的注解,并且指定验证器
- 一个验证器的实现
自定义验证注解
考虑有一个API,接收一个Student
对象,并希望对象里的age
域的值是奇数,这时候就可以创建以下注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = AgeValidator.class)
public @interface Odd {
String message() default "Age Must Be Odd";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
其中:
@Target
指明这个注解要作用在什么地方,可以是对象、域、构造器等,因为要作用在age
域上,因此这里选择FIELD
@Retention
指明了注解的生命周期,可以有SOURCE
(仅保存在源码中,会被编译器丢弃),CLASS
(在class文件中可用,会被VM丢弃)以及RUNTIME
(在运行期也被保留),这里选择了生命周期最长的RUNTIME
@Constraint
是最关键的,它表示这个注解是一个验证注解,并且指定了一个实现验证逻辑的验证器message()
指明了验证失败后返回的消息,此方法为@Constraint
要求groups()
和payload()
也为@Constraint
要求,可默认为空,详细用途可以查看@Constraint
文档
创建验证器
有了注解之后,就需要一个验证器来实现验证逻辑:
public class AgeValidator implements ConstraintValidator<Odd,Integer> {
@Override
public void initialize(Odd constraintAnnotation) {
}
@Override
public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) {
return age % 2 != 0;
}
}
其中:
- 验证器有两个类型参数,第一个是所属的注解,第二个是注解作用地方的类型,这里因为作用在
age
上,因此这里用了Integer
initialize()
可以在验证开始前调用注解里的方法,从而获取到一些注解里的参数,这里用不到isValid()
就是判断是否合法的地方
应用注解
注解和验证器创建好之后,就可以使用注解了:
public class Student {
@Odd
private int age;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@RestController
public class StudentResource {
@PostMapping("/student")
public String addStudent(@Valid @RequestBody Student student) {
return "Student Created";
}
}
在需要启用验证的地方加上@Valid
注解,这时候如果请求里的Student
年龄不是奇数,就会得到一个400
响应:
{
"timestamp": "2018-08-15T17:01:44.598+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"Odd.student.age",
"Odd.age",
"Odd.int",
"Odd"
],
"arguments": [
{
"codes": [
"student.age",
"age"
],
"arguments": null,
"defaultMessage": "age",
"code": "age"
}
],
"defaultMessage": "Age Must Be Odd",
"objectName": "student",
"field": "age",
"rejectedValue": 12,
"bindingFailure": false,
"code": "Odd"
}
],
"message": "Validation failed for object=‘student‘. Error count: 1",
"path": "/student"
}
也可以手动来处理错误,加上一个BindingResult
来接收验证结果即可:
@RestController
public class StudentResource {
@PostMapping("/student")
public String addStudent(@Valid @RequestBody Student student, BindingResult validateResult) {
if (validateResult.hasErrors()) {
return validateResult.getAllErrors().get(0).getDefaultMessage();
}
return "Student Created";
}
}
这时候如果验证出错,便只会返回一个状态为200
,内容为Age Must Be Odd的响应。
以上是关于如何自定义注解?都需要写啥?以下是自己写的残例,有问题,求帮助!的主要内容,如果未能解决你的问题,请参考以下文章
解决echarts使用renderItem自定义图表时的残影问题