Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot 2 and method parameter validation

I created the following service interface:

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);

}

but the following invocation:

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

passes the @NotNull validation for isBot parameter. How to correctly configure Spring Boot and my service in order to take into account @NonNull annotation and prevent method execution in case of null parameter?

like image 773
alexanoid Avatar asked Sep 07 '25 05:09

alexanoid


2 Answers

I played around with this problem for a bit.

Your code looks fine to me: Make sure that the implementation of UserService also has the validation annotations present.

Ensure that you allow Spring to create the Bean; it should work as you expect.

Example

Service Definition

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);
}

Service Implementation

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;
    }
}

Testcase

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(""));
    }

}

Testcases are green for me.

Github: https://github.com/almac777/spring-validation-playground

Source: https://www.baeldung.com/javax-validation-method-constraints

HTH!

like image 178
almac777 Avatar answered Sep 09 '25 00:09

almac777


You need to make sure that @Validated annotation is used on 'class' which method arguments will need to be validated and Spring configuration need to be added

@Configuration
public class MethodValidationConfig {

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}
like image 43
walter33 Avatar answered Sep 09 '25 01:09

walter33