Custom annotations in Java for data validation

Source: Internet
Author: User

API development often encountered some validation of the request data, at this time if the use of annotations there are two benefits, one is the validation logic and business logic separation, code clear, and the second is the validation logic can be easily reused, just need to verify the place to add annotations.

Java provides some basic validation annotations, such as, @NotNull @Size but more generally, the need for custom validation logic, which allows you to implement a validation note on your own, which is simple and requires only two things:

    • A custom annotation, and specifies the validator
    • Implementation of a validator
Custom validation Annotations

Consider an API that receives an Student object and expects the value of the field in the object to be an age odd number, so that the following annotations can be created:

@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 {};}

which

    • @TargetIndicates where this annotation is to be used, such as object, domain, constructor, and so on, because it is age on the domain, so chooseFIELD
    • @RetentionIndicates the lifetime of the annotations, which can be SOURCE (stored only in the source code, discarded by the compiler), CLASS (available in the class file, discarded by the VM), and RUNTIME (also retained at runtime), where the longest life cycle is selected.RUNTIME
    • @ConstraintIs the most critical, it indicates that the annotation is a validation note and that a validator is specified that implements the validation logic
    • message()Indicates the message returned after a validation failure, as required by this method @Constraint
    • groups()And payload() also for @Constraint requirements, can default to empty, detailed use can view the @Constraint document
Creating validators

With annotations, you need a validator to implement the validation logic:

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;    }}

which

    • The validator has two type parameters, the first one is the annotation to which it belongs, the second is the type of place where the annotation is acting, because of the effect age , so here is theInteger
    • initialize()You can invoke the methods in the annotations before the validation begins to get the parameters in some annotations, which are not used here.
    • isValid()Is the place to judge whether it's legal.
Application Notes

Once the annotations and validators have been created, you can use annotations:

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;    }}
@RestControllerpublic class StudentResource {    @PostMapping("/student")    public String addStudent(@Valid @RequestBody Student student) {        return "Student Created";    }}

Add annotations where validation is required @Valid , and if the age in the request Student is not odd, a response is given 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"}

You can also manually handle errors, plus one BindingResult to receive validation results:

@RestControllerpublic 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";    }}

At this point, if the validation goes wrong, only a response with the status of must be odd is returned 200 .

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.