Рекомендации по проверке Java Bean

Spring Boot Hibernate

Проверка параметров является важным процессом при разработке нашей программы. Когда пользователь заполняет форму на странице внешнего интерфейса, программа js внешнего интерфейса проверяет правильность параметров.Когда данные достигают внутреннего конца, чтобы предотвратить вредоносные операции и сохранить надежность программы. , серверной части также необходимо проверить данные. Самый простой способ проверить внутренние параметры — это оценить непосредственно бизнес-метод и продолжить выполнение после того, как оценка будет успешной. Но что это дает нам, так это связанность и избыточность кода. Когда нам нужно проверить в нескольких местах, нам нужно вызывать программу проверки в каждом месте, что приводит к избыточному и неприглядному коду.

Итак, как изящно проверить параметры? JSR303 должен решить эту проблему.Эта статья в основном знакомит с использованием JSR303, Hibernate Validator и других инструментов проверки, а также с использованием пользовательских аннотаций проверки.

Введение в структуру проверки

JSR303 — это набор стандартов для проверки параметров JavaBean. Он определяет множество общих аннотаций проверки. Мы можем напрямую добавить эти аннотации к свойствам нашего JavaBean, а затем мы можем проверить, когда нам нужно проверить. Примечания следующие:

Валидатор Hibernate расширяет аннотации проверки на основе JSR303.Расширенные аннотации следующие:

Spring validator также расширяет возможности jsr303 и реализует проверку параметров метода и возвращаемых значений.

Spring предоставляет класс MethodValidationPostProcessor для проверки метода.

Код

Добавить зависимости пакета JAR

Добавьте следующие зависимости в pom.xml:

        <!--jsr 303-->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <!-- hibernate validator-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.0.Final</version>
        </dependency>

 

Простейшая проверка параметров

1. Добавьте аннотации проверки в модель

public class Book {
    private long id;

    /**
     * 书名
     */
    @NotEmpty(message = "书名不能为空")
    private String bookName;
    /**
     * ISBN号
     */
    @NotNull(message = "ISBN号不能为空")
    private String bookIsbn;
    /**
     * 单价
     */
    @DecimalMin(value = "0.1",message = "单价最低为0.1")
private double price; // getter setter ....... }

 

2. Используйте эту проверку в контроллере

 /**
     * 添加Book对象
     * @param book
     */
    @RequestMapping(value = "/book", method = RequestMethod.POST)
    public void addBook(@RequestBody @Valid Book book) {
        System.out.println(book.toString());
    }

 

При доступе к этому почтовому интерфейсу, если параметр не соответствует определению в модели, программа выдаст исключение 400 и запросит сообщение об ошибке.

Пользовательские аннотации проверки

Хотя jSR303 и Hibernate Validtor предоставили множество аннотаций проверки, столкнувшись со сложной проверкой параметров, они по-прежнему не могут удовлетворить наши требования.В настоящее время нам необходимо настроить аннотации проверки.

Ниже приведена пользовательская аннотация проверки с примером «массив списка не может содержать нулевые элементы».

1. Аннотации определяются следующим образом:

package com.beiyan.validate.annotation;

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

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

/**
 * 自定义参数校验注解
 * 校验 List 集合中是否有null 元素
 */

@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = ListNotHasNullValidatorImpl.class)////此处指定了注解的实现类为ListNotHasNullValidatorImpl

public @interface ListNotHasNull {

    /**
     * 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义
     */
    int value() default 0;

    String message() default "List集合中不能含有null元素";

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

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

    /**
     * 定义List,为了让Bean的一个属性上可以添加多套规则
     */
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        ListNotHasNull[] value();
    }
}

 

2. Аннотировать класс реализации:

package com.beiyan.validate.annotation;

import org.springframework.stereotype.Service;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;

/**
 * 自定义注解ListNotHasNull 的实现类
 * 用于判断List集合中是否含有null元素
 */

@Service
public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List> {

    private int value;

    @Override
    public void initialize(ListNotHasNull constraintAnnotation) {
        //传入value 值,可以在校验中使用
        this.value = constraintAnnotation.value();
    }

    public boolean isValid(List list, ConstraintValidatorContext constraintValidatorContext) {
        for (Object object : list) {
            if (object == null) {
                //如果List集合中含有Null元素,校验失败
                return false;
            }
        }
        return true;
    }

}

 

3. Добавьте аннотации к модели:

public class User {

//其他参数 ....... /** * 所拥有的书籍列表 */ @NotEmpty(message = "所拥有书籍不能为空") @ListNotHasNull(message = "List 中不能含有null元素") @Valid private List<Book> books; //getter setter 方法....... }

 

Метод использования такой же, как и выше, просто добавьте @Valid к модели, которую необходимо проверить.

Групповая проверка

Для одной и той же модели у нас есть разные проверки параметров при добавлении и изменении. В настоящее время нам нужно определить групповую проверку. Шаги следующие

1. Определите два пустых интерфейса, представляющих добавление и изменение правил проверки объекта Person соответственно.

/**
 * 可以在一个Model上面添加多套参数验证规则,此接口定义添加Person模型新增时的参数校验规则
 */
public interface PersonAddView {
}

/**
 * 可以在一个Model上面添加多套参数验证规则,此接口定义添加Person模型修改时的参数校验规则
 */
public interface PersonModifyView {
}

 

2. При добавлении аннотаций в Модель используйте указанную группировку

public class Person {
    private long id;
    /**
     * 添加groups 属性,说明只在特定的验证规则里面起作用,不加则表示在使用Deafault规则时起作用
     */
    @NotNull(groups = {PersonAddView.class, PersonModifyView.class}, message = "添加、修改用户时名字不能为空", payload = ValidateErrorLevel.Info.class)
    @ListNotHasNull.List({
            @ListNotHasNull(groups = {PersonAddView.class}, message = "添加上Name不能为空"),
            @ListNotHasNull(groups = {PersonModifyView.class}, message = "修改时Name不能为空")})
    private String name;

    @NotNull(groups = {PersonAddView.class}, message = "添加用户时地址不能为空")
    private String address;

    @Min(value = 18, groups = {PersonAddView.class}, message = "姓名不能低于18岁")
    @Max(value = 30, groups = {PersonModifyView.class}, message = "姓名不能超过30岁")
    private int age;
  //getter setter 方法......
}

 

3. Включить проверку

На данный момент он отличается от того, что было до включения контрольной суммы, и вам нужно указать, какой набор правил включить

  /**
     * 添加一个Person对象
     * 此处启用PersonAddView 这个验证规则
     * 备注:此处@Validated(PersonAddView.class) 表示使用PersonAndView这套校验规则,若使用@Valid 则表示使用默认校验规则,
     * 若两个规则同时加上去,则只有第一套起作用
     */
    @RequestMapping(value = "/person", method = RequestMethod.POST)
    public void addPerson(@RequestBody @Validated({PersonAddView.class, Default.class}) Person person) {
        System.out.println(person.toString());
    }

    /**
     * 修改Person对象
     * 此处启用PersonModifyView 这个验证规则
     */
    @RequestMapping(value = "/person", method = RequestMethod.PUT)
    public void modifyPerson(@RequestBody @Validated(value = {PersonModifyView.class}) Person person) {
        System.out.println(person.toString());
    }

 

Проверка Spring на уровне метода валидатора

Проверка валидатора JSR и Hibernate может проверять только свойства объекта, а не один параметр. Spring расширился на этой основе и добавил перехватчик MethodValidationPostProcessor, который может проверять параметры метода. Реализация выглядит следующим образом:

1. Создайте экземпляр MethodValidationPostProcessor

@Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

 

2. Добавьте @Validated в класс, в котором вы хотите реализовать проверку параметров метода, как показано ниже.

@RestController
@Validated
public class ValidateController {
}

 

3. Добавьте в метод правило проверки:

  @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String paramCheck(@Length(min = 10) @RequestParam String name) {
        System.out.println(name);
        return null;
    }

 

Когда проверка параметра выше метода не удалась, среда Spring выдает исключение

{
  "timestamp": 1476108200558,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "javax.validation.ConstraintViolationException",
  "message": "No message available",
  "path": "/test"
}

Отныне параметры можно проверить элегантно

Напишите следующие слова:

В этой статье перечислены только несколько часто используемых методов проверки, на самом деле их гораздо больше:

Интернационализированное отображение информации о проверке,

Проверка параметров комбинации,

Используйте выражения EL в сообщении,

Информация о проверке привязки к ModelAndView и т. д. здесь не приводится.Также хорошо написаны следующие статьи.Читатели могут обратиться к:

Привязать проверочную информацию к ModelAndViewWoohoo.void cn.com/blog/983836…

Интеграция проверки компонентов 1.1 (JSR-349) в SpringMVC№ OSCHINA.net/Global1208/No…

 

Весь код этой статьи был загружен в китайский репозиторий git с открытым исходным кодом:git.OSCHINA.net/submerged/VA…