SpringBoot__JSR303 Verifies the Input Parameters

Program Tool Class:

package com.liutao.utilitys;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * Parametric Verification Tool Class
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */
public class ValidateUtility {
    /**
     * Determine whether there is a validation error message
     * @param result
     * @return
     */
    public static String judgeValidate(BindingResult result, HttpServletResponse response) {
        if(result.hasErrors()){
            List<ObjectError> list = result.getAllErrors();
            StringBuilder stringBuilder = new StringBuilder();
            for(ObjectError  error:list){
                stringBuilder.append("\n"+error.getDefaultMessage());
            }
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            return stringBuilder.toString();
        }
        return "ok";
    }
}


I. Common Verification Notes
(1) Common labels
@ Null. The annotated element must be null
@ NotNull The annotated element cannot be null
@ AssertTrue. The annotated element must be true
@ AssertFalse The commented element must be false
@ Min(value) The commented element must be a number whose value must be greater than or equal to the specified minimum
@ Max(value) The commented element must be a number whose value must be less than or equal to the specified maximum
@ DecimalMin(value) The commented element must be a number whose value must be greater than or equal to the specified minimum
@ DecimalMax(value) The commented element must be a number whose value must be less than or equal to the specified maximum
@ Size(max,min) The size of the annotated element must be within the specified range.
@ Digits(integer,fraction) annotated elements must be a number whose value must be acceptable
@ Past The annotated element must be a past date
@ Future. The annotated element must be a future date
@ The annotated element of Pattern(value) must conform to the specified regular expression.
@ Email annotated elements must be e-mail addresses
@ Length's annotated string must be within the specified range
@ NotEmpty. The commented string must be non-empty
@ Range The annotated element must be within the appropriate range
(2) Examples

package com.liutao.model;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

/**
 * User Data Template
 *
 * @author LIUTAO
 * @version 2017/3/29
 * @see
 * @since
 */
public class User {

    @NotEmpty(message = "Name cannot be empty")
    private String name;
    private Integer age;

    @NotEmpty(message = "Password cannot be empty")
    @Length(min = 6,max = 20,message = "Password length should be greater than 6 bits and less than 20 bits")
    private String password;

    public User() {
    }

    public User(String name, Integer age, String password) {
        this.name = name;
        this.age = age;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", password='" + password + '\'' +
                '}';
    }
}

package com.liutao.controller;

import com.liutao.model.User;
import com.liutao.utilitys.ValidateUtility;
import com.wordnik.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

/**
 * User Control Layer
 *
 * @author LIUTAO
 * @version 2017/3/29
 * @see
 */

@RestController
@Api(value = "test")
@RequestMapping("/liutao/v1")
public class UserController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @PostMapping(value = "/user")
    public
    @ResponseBody
    String postUser(@Valid @RequestBody User user, BindingResult result, HttpServletResponse response) {
        return ValidateUtility.judgeValidate(result,response);
    }
}
The above running program can be tested to see the corresponding error information returned.

2. Custom Validation Label
For some requirements, we need to define our own tags when the existing tags can not meet our needs. Examples are as follows:
(1) Defining labels

package com.liutao.annotation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * Demonstration of custom parameter validation annotations
 * Check whether null elements exist in list sets
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 */
@Target({ANNOTATION_TYPE, METHOD, ElementType.FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = ListNotHasNullValidatorImpl.class)//The annotated implementation class is specified here as ListNotHasNullValidatorImpl
public @interface ListNotHasNull {
    /**
     * Adding the value attribute can be used as a condition for validation. If not, remove the definition here.
     */
    int value() default 0;

    String message() default "List Cannot contain in a set null element";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    /**
     * Define List so that multiple sets of rules can be added to an attribute of a Bean
     */
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        ListNotHasNull[] value();
    }
}
(2) Label Verification Implementation Class

package com.liutao.annotation;
import org.springframework.stereotype.Service;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;

/**
 * Demonstrate the implementation class for implementing ListNotHasNull check annotations
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 */
@Service
public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List> {

    private int value;

    @Override
    public void initialize(ListNotHasNull constraintAnnotation) {
        //Input value, which can be used in validation
        this.value = constraintAnnotation.value();
    }

    public boolean isValid(List list, ConstraintValidatorContext constraintValidatorContext) {
        for (Object object : list) {
            if (object == null) {
                //If the List collection contains Null elements, the validation fails
                return false;
            }
        }
        return true;
    }

}
(3) Required data model

package com.liutao.model;
/**
 * Employee Data Model
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 */
public class Employee {
    private String name;
    private String age;
    private String cellPhone;

    public Employee() {
    }

    public Employee(String name, String age, String cellPhone) {
        this.name = name;
        this.age = age;
        this.cellPhone = cellPhone;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getCellPhone() {
        return cellPhone;
    }

    public void setCellPhone(String cellPhone) {
        this.cellPhone = cellPhone;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", cellPhone='" + cellPhone + '\'' +
                '}';
    }
}

package com.liutao.model;
import com.liutao.annotation.ListNotHasNull;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.Valid;
import java.util.List;

/**
 * Corporate Data Model
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */
public class Company {

    @NotEmpty(message = "Company name cannot be empty")
    private String name;

    @Length(min = 2,max = 20,message = "Address information must be between 2 and 20 characters")
    private String address;

    @NotEmpty(message = "Employee Information Can't Be Empty")
    @ListNotHasNull
    @Valid
    private List<Employee> employees;

    public Company() {
    }

    public Company(String name, String address, List<Employee> employees) {
        this.name = name;
        this.address = address;
        this.employees = employees;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Company{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", employees=" + employees +
                '}';
    }
}
From the Company above, we can see that the custom @ListNotHasNull tag has been used.
(4) Testing Controller

package com.liutao.controller;

import com.liutao.model.Company;
import com.liutao.utilitys.ValidateUtility;
import com.wordnik.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

/**
 * Company Controller
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 */
@RestController
@Api(value = "test company")
@RequestMapping("/liutao/v1")
public class CompanyController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @PostMapping(value = "/company")
    public String postCompany(@Valid @RequestBody Company company, BindingResult result,HttpServletResponse response){
        return ValidateUtility.judgeValidate(result,response);
    }
}
The above program can see the corresponding error message after the corresponding test.
Group Verification
What should we do when the validation for the same model is different? For example, when adding and modifying the same model? At this point, we need to use group validation.
(1) Define interfaces that represent modifying and adding validation rules, respectively

package com.liutao.validateInterface;

/**
 * person Parametric Checking Rules for New Model
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */
public interface PersonAddView {
}

package com.liutao.validateInterface;

/**
 * person Parametric Checking Rules for Model Modification
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */
public interface PersonUpdateView {
}
(2) Adding corresponding checking rules to the data model

package com.liutao.model;
import com.liutao.validateInterface.PersonAddView;
import com.liutao.validateInterface.PersonUpdateView;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

/**
 * person data model
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 */
public class Person {
    private Long id;

    /**
     * Adding groups to the validation label only works within specific validation rules. If not, it works within the default validation rules.
     */

    @NotNull(groups = {PersonAddView.class},message = "Added name cannot be empty")
    @Length(min = 2,max = 10,groups = {PersonUpdateView.class},message = "Names must be between 2 and 10 characters when modified")
    private String name;

    @NotNull(groups = {PersonAddView.class}, message = "Address cannot be empty when adding users")
    private String address;

    @Min(value = 18, groups = {PersonAddView.class}, message = "No younger than 18")
    @Max(value = 30, groups = {PersonUpdateView.class}, message = "Age should not exceed 30")
    private Integer age;

    public Person() {
    }

    public Person(Long id, String name, String address, Integer age) {
        this.id = id;
        this.name = name;
        this.address = address;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", age=" + age +
                '}';
    }
}
(3) Adding validation to parameters

package com.liutao.controller;

import com.liutao.model.Person;
import com.liutao.utilitys.ValidateUtility;
import com.liutao.validateInterface.PersonAddView;
import com.liutao.validateInterface.PersonUpdateView;
import com.wordnik.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.groups.Default;

/**
 * Personnel Controller
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */
@RestController
@Api(value = "test person")
@RequestMapping("/liutao/v1")
public class PersonController {

    private Logger logger = LoggerFactory.getLogger(PersonController.class);
    /**
     * The @Validated(PersonAddView.class) denotes the use of the PersonAndView set of validation rules, and the @Valid denotes the use of the default validation rules.
     * If two rules are added at the same time, only the first one will work.
     *
     * @param person
     */
    @PostMapping(value = "/person")
    public String addPerson(@RequestBody @Validated({PersonAddView.class, Default.class}) Person person, BindingResult result,HttpServletResponse response) {
        logger.debug("enter post person");
        logger.debug("the information of person :"+ person);
        return ValidateUtility.judgeValidate(result,response);
    }

    /**
     * Modify Person object
     * Enable the PersonModifyView validation rule here
     * @param person
     */
    @PutMapping(value = "/person")
    public String modifyPerson(@RequestBody @Validated(value = {PersonUpdateView.class}) Person person, BindingResult result,HttpServletResponse response) {
        logger.debug("enter put person");
        logger.debug("the information of person :"+ person);
        return ValidateUtility.judgeValidate(result,response);
    }
}
According to the above procedure, the corresponding test results can be obtained.
4. Verification of non-object parameters in Controller method
If the parameters we pass in need not be encapsulated as objects, then the verification of the parameters must be done using the parameters.

(1) Adding parameter validation configuration classes

package com.liutao.config;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ValidationException;

/**
 * Parameter Verification Configuration Class
 *
 * @author LIUTAO
 * @version 2017/5/18
 * @see
 */
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handle(ValidationException exception) {
        return "Input parameters do not meet the requirements";
    }
}

(2) Adding parameter validation to Controller

package com.liutao.controller;

import com.wordnik.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;

/**
 * Employee Controller
 *
 * @author LIUTAO
 * @version 2017/5/19
 * @see
 * @since
 */

@RestController
@Api(value = "test employee")
@RequestMapping("/liutao/v1")
@Validated
public class EmployeeController {

    private Logger logger = LoggerFactory.getLogger(EmployeeController.class);

    @GetMapping("/employee")
    @ResponseStatus(HttpStatus.OK)
    public @ResponseBody
    String check(@RequestParam @Min(value = 10,message = "Name length must be greater than 10") int age) {
        logger.debug("enter employee get");
        return "ok";
    }
}
The above programs can be tested to get the test results.

Refer to gitHub address for source code: SpringBoot__validatot






Keywords: Java Hibernate less Attribute

Added by lip9000 on Sat, 29 Jun 2019 22:56:39 +0300