欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA中通过自定义注解进行数据验证的方法

程序员文章站 2024-02-24 19:50:46
前言 最近为了工作也为了更加深入了解掌握java注解的使用,决定自定义注解来实现数据验证。 api开发中经常会遇到一些对请求数据进行验证的情况,这时候如果使用注解就有两...

前言

最近为了工作也为了更加深入了解掌握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的响应。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。