Я использую spring-boot version:2.0.5
Грейдл:
buildscript {
ext {
springBootVersion = '2.0.5.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 = 'io.reflectoring'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 11
repositories {
mavenCentral()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
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()
}
Контроллер
@RestController
class ValidateRequestBodyController {
@PostMapping("/validateBody")
ResponseEntity<String> validateBody(@Valid @RequestBody Input input) {
return ResponseEntity.ok("valid");
}
}
Класс проверки
class InputWithCustomValidator {
@IpAddress
private String ipAddress;
// ...
}
class IpAddressValidator implements ConstraintValidator<IpAddress, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
Pattern pattern =
Pattern.compile("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$");
Matcher matcher = pattern.matcher(value);
//step 1
if (!matcher.matches()) {
return 400;
}
//Step 2
if (ipAddress already in DB) {
return 409; //conflict with other IP address
}
//Also I need to return different exception based on diff validations
}
}
Совет по контроллеру
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse> handle(ValidationException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(e.getMessage());
}
Если я выбрасываю customException из моего валидатора, то я получаю сообщение об ошибке ниже, даже если у меня есть соответствующий controllerAdvice для него,
{
"code": "invalid_request"
"description": "HV000028: Unexpected exception during isValid call."
}
Всегда я получаю 400 Bad request, так как у меня есть controllerAdvice, который всегда возвращает 400.
Здесь я хотел бы добиться того, есть ли возможность вернуть customException с кодом состояния или в любом случае вернуть другой код состояния из валидатора? Я вижу похожие сообщения в StackOverflow, но ответа не было. Я также проверил другие сообщения, но не нашел их полезными.