SpringBoot2中的參數校驗,以及異常統一處理


一、添加依賴在pom.xml文件中

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

二、實體類參數校驗

1)實體對象示例

package com.xc.common.model;

import lombok.Data;

import javax.validation.constraints.*;

/**
 * Vaild測試對象
 * @author Administrator
 */
@Data
public class VaildTestModel {

    @NotNull(message = "Id不能為空")
    private Long id;

    @NotNull(message = "用戶賬號不能為空")
    @Size(min = 6, max = 11, message = "賬號長度必須是6-11個字符")
    private String account;

    @NotNull(message = "用戶密碼不能為空")
    @Size(min = 6, max = 11, message = "密碼長度必須是6-16個字符")
    private String password;

    @NotNull(message = "用戶郵箱不能為空")
    @Email(message = "郵箱格式不正確")
    private String email;

    @NotEmpty(message = "姓名不能為空")
    private String name;

    @Max(value = 18,message = "年齡不能超過18歲")
    private String age;
    
    @Max(value = 1, message = "性別只能為0和1: 0=女1=男")
    @Min(value = 0, message = "性別只能為0和1: 0=女1=男")
    private Short sex;
}

2)controller示例

package com.xc.web.controller;


import com.xc.common.model.ResponseVO;
import com.xc.common.model.VaildTestModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

/**
 * 測試類
 * http://localhost:9004/webacttest/doc.html#/home
 * @author Administrator
 */
@Slf4j
@RestController
@Api(description = "測試接口")
@RequestMapping("test")
@Validated
public class TestController {

    @ApiOperation("測試@validated注解 類上")
    @PostMapping("testValidated2")
    public ResponseVO testValidated2(@Valid @RequestBody @ApiParam("VaildTestModel對象") VaildTestModel vaildTestModel) {
        return ResponseVO.successInstance(vaildTestModel.getId());
    }
}

3)全局異常處理類

/**
 * 全局異常處理器
 * @author Administrator
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 處理所有校驗失敗的異常(MethodArgumentNotValidException異常)
     * 設置響應狀態碼為400
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseVO handleBindGetException(MethodArgumentNotValidException ex) {
        // 獲取所有異常
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(x -> x.getDefaultMessage())
                .collect(Collectors.toList());
        return ResponseVO.errorInstance(String.join(",", errors));
    }

}

4)測試結果

 

 

 

 5)快速失敗模式

package com.xc.common.exception;

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 * 效驗模式:如果出現多個字段效驗失敗,會返回所有的驗證失敗錯誤信息。通常情況下,當第一個字段/參數效驗失敗時,直接返回。
 * 普通模式:默認使用的就是普通模式,校驗完所有的屬性之后,返回所有的驗證失敗信息。
 * 快速失敗模式:只要有一個字段效驗失敗,直接返回
 * @author Administrator
 */
@Configuration
public class ValidationConfig {
    /**
     * 效驗@RequestBody時,采用快速失敗模式
     */
    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                //快速失敗
                .failFast(true)
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    /**
     * 效驗@RequestParam時,采用快速失敗模式
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(Validator validator) {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        // 設置validator
        postProcessor.setValidator(validator);
        return postProcessor;
    }
}

二、單個參數校驗

1)直接在參數前加上校驗注解  注:類上必須加  @Validated 注解

package com.xc.web.controller;


import com.xc.common.model.ResponseVO;
import com.xc.common.model.VaildTestModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.Map;

/**
 * 測試類
 * http://localhost:9004/webacttest/doc.html#/home
 * @author Administrator
 */
@Slf4j
@RestController
@Api(description = "測試接口")
@RequestMapping("test")
@Validated
public class TestController {

    @ApiOperation(value = "測試@validated注解",notes = "返回輸入的參數")
    @GetMapping("testValidated")
    public ResponseVO testValidated(
            @RequestParam("param") @NotNull(message = "參數不能為空")
            @ApiParam(value = "參數", required = true, example = "0") String param
    ){
        return getConstant(param);
    }
}

2)全局處理函數

package com.xc.common.exception;

import com.xc.common.model.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 全局異常處理器
 * @author Administrator
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 處理所有校驗失敗的異常(MethodArgumentNotValidException異常)
     * 設置響應狀態碼為400
     * @param ex
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseVO handleBindGetException(MethodArgumentNotValidException ex) {
        // 獲取所有異常
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(x -> x.getDefaultMessage())
                .collect(Collectors.toList());
        return ResponseVO.errorInstance(String.join(",", errors));
    }

    /**
     * 處理所有參數校驗時拋出的異常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = ValidationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseVO handleBindException(ValidationException ex) {
        // 獲取所有異常
        List<String> errors = new LinkedList<String>();
        if(ex instanceof ConstraintViolationException){
            ConstraintViolationException exs = (ConstraintViolationException) ex;
            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            for (ConstraintViolation<?> item : violations) {
                errors.add(item.getMessage());
            }
        }
        return ResponseVO.errorInstance(String.join(",", errors));
    }

    /**
     * Controller參數綁定錯誤
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseVO handleMissingServletRequestParameterException(MissingServletRequestParameterException ex) {
        return ResponseVO.errorInstance(ex.getMessage());
    }

}

3)結果驗證

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM