[英]Spring Boot 2 and method parameter validation
我創建了以下服務接口:
import javax.validation.constraints.NotBlank;
import org.springframework.lang.NonNull;
import org.springframework.validation.annotation.Validated;
@Validated
public interface UserService {
User create(@NonNull Long telegramId, @NotBlank String name, @NonNull Boolean isBot);
}
但以下調用:
userService.create(telegramId, "Mike", null);
通過isBot
參數的@NotNull
驗證。 如何正確配置 Spring Boot 和我的服務,以便在null
參數的情況下考慮@NonNull
注釋並防止方法執行?
我在這個問題上玩了一會兒。
您的代碼對我來說看起來不錯:確保UserService
的實現也存在驗證注釋。
確保您允許 Spring 創建 Bean; 它應該按您的預期工作。
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Validated
public interface GreetingService {
String greet(@NotNull @NotBlank String greeting);
}
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Service
public class HelloGreetingService implements GreetingService {
public String greet(@NotNull @NotBlank String greeting) {
return "hello " + greeting;
}
}
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import javax.validation.ConstraintViolationException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest
class HelloGreetingServiceTest {
@Autowired
private GreetingService helloGreetingService;
@Test
void whenGreetWithStringInput_shouldDisplayGreeting() {
String input = "john doe";
assertEquals("hello john doe", helloGreetingService.greet(input));
}
@Test
void whenGreetWithNullInput_shouldThrowException() {
assertThrows(ConstraintViolationException.class, () -> helloGreetingService.greet(null));
}
@Test
void whenGreetWithBlankInput_shouldThrowException() {
assertThrows(ConstraintViolationException.class, () -> helloGreetingService.greet(""));
}
}
測試用例對我來說是綠色的。
Github: https://github.com/almac777/spring-validation-playground
資料來源: https://www.baeldung.com/javax-validation-method-constraints
!
在實現 class 中使用相同的東西代替接口。 也可以編寫一個全局異常,例如:
@Order(Ordered.HIGHEST_PRECEDENCE)
@RestControllerAdvice
public class GlobalRestException extends ResponseEntityExceptionHandler {
...
...
/**
* Handle MethodArgumentNotValidException. Triggered when an object fails @Valid
* validation.
*
* @param ex the MethodArgumentNotValidException that is thrown when @Valid
* validation fails
* @param headers HttpHeaders
* @param status HttpStatus
* @param request WebRequest
* @return the ApiException object
*/
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
Error apiError = new Error(BAD_REQUEST);
apiError.setMessage("Validation error");
apiError.addValidationErrors(ex.getBindingResult().getFieldErrors());
apiError.addValidationError(ex.getBindingResult().getGlobalErrors());
return buildResponseEntity(apiError);
}
}
還有更多方法可以被覆蓋來處理不同類型的異常,例如:
/**
* Handles javax.validation.ConstraintViolationException. Thrown when @Validated
* fails.
*
* @param ex the ConstraintViolationException
* @return the ApiException object
*/
@ExceptionHandler(javax.validation.ConstraintViolationException.class)
protected ResponseEntity<Object> handleConstraintViolation(javax.validation.ConstraintViolationException ex) {
Error apiError = new Error(BAD_REQUEST);
apiError.setMessage("Validation error");
apiError.addValidationErrors(ex.getConstraintViolations());
return buildResponseEntity(apiError);
}
您需要確保在“類”上使用了@Validated
注釋,需要驗證 arguments 方法和需要添加 Spring 配置
@Configuration
public class MethodValidationConfig {
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.