Spring Boot 整合Hibernate Validator

Spring Boot 整合Hibernate Validator

依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.2.0.Final</version>
        </dependency>
    </dependencies>

controller

  • 記得添加 @Validated
@RestController
@Validated
public class TestController {

    @PostMapping("/valid")
    public String validator(@NotBlank(message = "{required}") String name,
                            @Email(message = "{invalid}") String email){
        return "success--->普通傳參";
    }

    @PostMapping("test2")
    public String user(@Valid User user) {
        return "success---->對象";
    }
}

entity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private static final long serialVersionUID = -2731598327208972274L;

    @NotBlank(message = "{required}")
    private String name;

    @Email(message = "{invalid}")
    private String email;
}

ValidationMessages.properties 配置 message 的參數

image-20220917124438855

全局異常處理

  • 未添加異常時

image-20220917104819150

  • 添加全局異常

image-20220917104811550

代碼

  • 裏面的 @Order(value = Ordered.HIGHEST_PRECEDENCE) 參數越小,優先級越高
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.List;
import java.util.Set;


@RestControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class GlobalExceptionHandler {

    /**
     * 統一處理請求參數校驗(普通傳參)
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handleConstraintViolationException(ConstraintViolationException e) {
        StringBuilder message = new StringBuilder();
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        for (ConstraintViolation<?> violation : violations) {
            Path path = violation.getPropertyPath();
            String[] pathArr = StringUtils.splitByWholeSeparatorPreserveAllTokens(path.toString(), ".");
            message.append(pathArr[1]).append(violation.getMessage()).append(",");
        }
        message = new StringBuilder(message.substring(0, message.length() - 1));
        return message.toString();
    }

    /**
     * 統一處理請求參數校驗(實體對象傳參)
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String validExceptionHandler(BindException e) {
        StringBuilder message = new StringBuilder();
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        for (FieldError error : fieldErrors) {
            message.append(error.getField()).append(error.getDefaultMessage()).append(",");
        }
        message = new StringBuilder(message.substring(0, message.length() - 1));
        return message.toString();

    }
}

其他註解的使用

  • Bean Validation 中內置的 constraint
@Valid 被注釋的元素是一個對象,需要檢查此對象的所有字段值
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Min(value) 被注釋的元素必須是一個數字,其值必須大於等於指定的最小值
@Max(value) 被注釋的元素必須是一個數字,其值必須小於等於指定的最大值
@DecimalMin(value) 被注釋的元素必須是一個數字,其值必須大於等於指定的最小值
@DecimalMax(value) 被注釋的元素必須是一個數字,其值必須小於等於指定的最大值
@Size(max, min) 被注釋的元素的大小必須在指定的範圍內
@Digits (integer, fraction) 被注釋的元素必須是一個數字,其值必須在可接受的範圍內
@Past 被注釋的元素必須是一個過去的日期
@Future 被注釋的元素必須是一個將來的日期
@Pattern(value) 被注釋的元素必須符合指定的正則表達式
  • Hibernate Validator 附加的 constraint
@Email 被注釋的元素必須是電子郵箱地址
@Length(min=, max=) 被注釋的字符串的大小必須在指定的範圍內
@NotEmpty 被注釋的字符串的必須非空
@Range(min=, max=) 被注釋的元素必須在合適的範圍內
@NotBlank 被注釋的字符串的必須非空
@URL(protocol=,
host=, port=,
regexp=, flags=) 被注釋的字符串必須是一個有效的url

@CreditCardNumber
被注釋的字符串必須通過Luhn校驗算法,
銀行卡,信用卡等號碼一般都用Luhn
計算合法性

@ScriptAssert
(lang=, script=, alias=) 要有Java Scripting API 即JSR 223
(「Scripting for the JavaTM Platform」)的實現
@SafeHtml
(whitelistType=,
additionalTags=) classpath中要有jsoup包

hibernate補充的註解中,最後3個不常用,可忽略。

主要區分下@NotNull @NotEmpty @NotBlank 3個註解的區別:

@NotNull 任何對象的value不能為null

@NotEmpty 集合對象的元素不為0,即集合不為空,也可以用於字符串不為null

@NotBlank 只能用於字符串不為null,並且字符串trim()以後length要大於0