Spring Boot 2 и проверка параметров метода - PullRequest
1 голос
/ 25 октября 2019

Я создал следующий интерфейс службы:

import javax.validation.constraints.NotBlank;

import org.springframework.lang.NonNull;
import org.springframework.validation.annotation.Validated;

import com.blablawork.domain.model.entity.user.User;

@Validated
public interface UserService {

    User create(@NonNull Long telegramId, @NotBlank String name, @NonNull Boolean isBot);

}

, но при следующем вызове:

userService.create(telegramId, "Mike", null);

проходит проверку @NotNull для параметра isBot. Как правильно настроить Spring Boot и мой сервис, чтобы учесть аннотацию @NonNull и предотвратить выполнение метода в случае параметра null?

Ответы [ 2 ]

3 голосов
/ 26 октября 2019

Я немного поиграл с этой проблемой.

Ваш код мне подходит: убедитесь, что реализация UserService также имеет аннотации проверки.

Убедитесь, чтовы позволяете Spring создавать Бин;он должен работать так, как вы ожидаете.

Пример

Определение сервиса

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

HTH!

0 голосов
/ 25 октября 2019

Используйте то же самое в классе реализации вместо интерфейса. Также можно написать одно глобальное исключение, например:

@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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...