Spring Boot教程之三十八: Spring boot中的验证

Spring Boot 中的验证

在本文中,通过Gradle项目,让我们了解如何验证示例应用程序并在浏览器中显示输出。该应用程序准备为Spring Boot类型,在本文中让我们了解如何通过命令行执行。

示例项目

项目结构:

 

因为这是 Gradle 项目,所以我们需要检查 

build.gradle

buildscript {
    ext {
        springBootVersion = '2.3.1.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'gfg'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 8

repositories {
    mavenCentral()
}

dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    
    // This is very much essential for validation
    implementation('org.springframework.boot:spring-boot-starter-validation')
    implementation('org.springframework.boot:spring-boot-starter-web')
    runtimeOnly('com.h2database:h2')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    testImplementation('org.junit.jupiter:junit-jupiter-engine:5.0.1')

    // these dependencies are needed when running with Java 11, since they
    // are no longer part of the JDK
    implementation('javax.xml.bind:jaxb-api:2.3.1')
    implementation('org.javassist:javassist:3.23.1-GA')
}

test{
    useJUnitPlatform()
}

gradlew.bat(Windows 的 Gradle 启动脚本)

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NULL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

现在让我们看看应用程序开始执行的主应用程序文件

SampleValidationApplication.java

  • Java

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

 

@SpringBootApplication

public class SampleValidationApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(SampleValidationApplication.class, args);

    }

}

让我们看看有助于以有意义且清晰的方式产生验证错误的必要文件

ErrorHandlingControllerAdviceSample.java

  • Java

import javax.validation.ConstraintViolation;

import javax.validation.ConstraintViolationException;

 

import org.springframework.http.HttpStatus;

import org.springframework.validation.FieldError;

import org.springframework.web.bind.MethodArgumentNotValidException;

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;

 

@ControllerAdvice

class ErrorHandlingControllerAdviceSample {

 

  @ExceptionHandler(ConstraintViolationException.class)

  @ResponseStatus(HttpStatus.BAD_REQUEST)

  @ResponseBody

  ValidationErrorResponse onConstraintValidationException(ConstraintViolationException e) {

    ValidationErrorResponse error = new ValidationErrorResponse();

    for (ConstraintViolation violation : e.getConstraintViolations()) {

      error.getViolations().add(new Violation(violation.getPropertyPath().toString(), violation.getMessage()));

    }

    return error;

  }

 

  @ExceptionHandler(MethodArgumentNotValidException.class)

  @ResponseStatus(HttpStatus.BAD_REQUEST)

  @ResponseBody

  ValidationErrorResponse onMethodArgumentNotValidException(MethodArgumentNotValidException e) {

    ValidationErrorResponse error = new ValidationErrorResponse();

    for (FieldError fieldError : e.getBindingResult().getFieldErrors()) {

      error.getViolations().add(new Violation(fieldError.getField(), fieldError.getDefaultMessage()));

    }

    return error;

  }

 

}

ValidationErrorResponse.java

  • Java

import java.util.ArrayList;

import java.util.List;

 

public class ValidationErrorResponse {

 

  private List<Violation> violations = new ArrayList<>();

 

  public List<Violation> getViolations() {

    return violations;

  }

 

  public void setViolations(List<Violation> violations) {

    this.violations = violations;

  }

}

Violation.java

  • Java

public class Violation {

 

  private final String fieldName;

 

  private final String message;

 

  public Violation(String fieldName, String message) {

    this.fieldName = fieldName;

    this.message = message;

  }

 

  public String getFieldName() {

    return fieldName;

  }

 

  public String getMessage() {

    return message;

  }

}

ValidateGivenParametersByController.java

这是控制器文件,我们可以在其中放置用于条件检查的注释

  • Java

import javax.validation.ConstraintViolationException;

import javax.validation.constraints.Min;

import javax.validation.constraints.Max;

import javax.validation.constraints.Email;

import javax.validation.constraints.Positive;

import javax.validation.constraints.NegativeOrZero;

 

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.validation.annotation.Validated;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.bind.annotation.RestController;

 

@RestController

@Validated

class ValidateGivenParametersByController {

 

  @GetMapping("/validatePathVariable/{id}")

  ResponseEntity<String> validatePathVariable(@PathVariable("id") @Min(5) int id) {

    return ResponseEntity.ok("valid");

  }

 

  @GetMapping("/validateRequestParameterWithMin")

  ResponseEntity<String> validateRequestParameterWithMin(@RequestParam("id") @Min(0) int id) {

    return ResponseEntity.ok("valid");

  }

   

  @GetMapping("/validateRequestParameterWithMax")

  ResponseEntity<String> validateRequestParameterWithMax(@RequestParam("id") @Max(5) int id) {

    return ResponseEntity.ok("valid");

  }

   

  @GetMapping("/validateRequestParameterWithEmailId")

  ResponseEntity<String> validateRequestParameterWithEmailId(@Email @RequestParam(name = "emailId")  String emailId) {

    return ResponseEntity.ok("valid");

  }

   

  @GetMapping("/validateRequestParameterWithPositive")

  ResponseEntity<String> validateRequestParameterWithPositive(@Positive @RequestParam(name = "id")  int id) {

    return ResponseEntity.ok("valid");

  }

   

  @GetMapping("/validateRequestParameterWithNegativeOrZero")

  ResponseEntity<String> validateRequestParameterWithNegativeOrZero(@NegativeOrZero @RequestParam(name = "id")  int id) {

    return ResponseEntity.ok("valid");

  }

 

  @ExceptionHandler(ConstraintViolationException.class)

  @ResponseStatus(HttpStatus.BAD_REQUEST)

  @ResponseBody

  String handleConstraintViolationException(ConstraintViolationException e) {

    return "Given input is not valid due to validation error: " + e.getMessage();

  }

 

}

通过命令行,我们可以按如下方式执行项目

 

现在让我们测试以下内容

测试 1:

http://localhost:8080/validatePathVariable/90 

 这是有效的,因为我们的代码中 id 应该是 @Min(5))。同时,如果我们传递 

http://localhost:8080/validatePathVariable/1

将会抛出错误

 

测试2:

http://localhost:8080/validateRequestParameterWithMin?id=-10

这里应用了@Min(0),因此我们可以在下面看到验证错误消息

 

测试 3:

http://localhost:8080/validateRequestParameterWithMax?id=10

这里应用了@Max(5),因此 

 

测试 4:

http://localhost:8080/validateRequestParameterWithEmailId?emailId=a.com

这里 emailId 没有正确给出

 

测试 5:

http://localhost:8080/validateRequestParameterWithPositive?id=-200 

因此仅接受正数

 

测试 6:

http://localhost:8080/validateRequestParameterWithNegativeOrZero?id=100

因此仅接受负数或零

 

最后

在整个项目中,我们可以使用必要的注释并验证输入字段。我们还可以给出适当的错误消息,使软件更高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潜洋

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值