I wanted to use bean-validation for parameters of a @RestController method, as mentioned in #6228
I am using SpringBoot version 1.5.0.BUILD-SNAPSHOT and wanted to use method validation by adding a @Validated annotation on my controller and then constraints on my method.
@RestController
@Validated
public class HelloController {
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
@RequestMapping(value = "/{uid}", method = RequestMethod.GET)
public String userById(@PathVariable @Size(max = 12) final String uid) {
return "Hello :"+uid;
}
@ExceptionHandler(value = {ConstraintViolationException.class})
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleValidationFailure(ConstraintViolationException ex) {
StringBuilder messages = new StringBuilder();
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
messages.append(violation.getMessage() + "\n");
}
return messages.toString();
}
The validation works when I start up my service but my test in MockMvc fails against expected behavior of throwing a Constraint Violation exception when a constraint is violated.
The below test should fail due to violation of size constraint since I've set @Size(max = 12)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
@ActiveProfiles(profiles = "test")
public class HelloControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void getUserException() throws Exception {
mockMvc.perform(get("/123222333322223"))
.andExpect(status().isOk())
.andExpect(content().string(equalToIgnoringCase("Hello :123222333322223")));
}
}
My pom.xml file looks like
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.0.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
I am working off the sample Spring boot project from https://github.com/spring-guides/gs-spring-boot.git
Validation is not enabled by default by @WebMvcTest (slice tests switch off auto-config and only enables a few of them explicitly). I guess we could add it to the list for @WebMvcTest.
Hello, I am solving the very same issue, but your answer isn't very descriptive to me. May I ask for final solution or more concrete hints how to solve the issue? Thanks
@maruskak this issue is resolved so Validation is auto-configured with WebMvcTest as of 1.5
@maruskak You can also add LocalValidatorFactoryBean and maven dependency by yourself.
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
Adds dependency
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
<scope>test</scope>
</dependency>
@ericxu131 there is a validation starter and no need to provide versions in the pom directly.
i am facing the same issue. it is not fixed yet ? am using Spring BOOT 1.5.10 RELEASE
@selvaebi We believe was fixed in 1.5.0.RC1 by commit d8d5950 on Dec 15, 2016. If you're still having trouble please open a new issue and provides a sample application that shows the problem.
If you add following snippet it should work as it worked for me as well.
@Before
public void setup() throws Exception {
this.mockMvc = standaloneSetup(screeningApiResources)
.setControllerAdvice(new CustomExceptionHandler(), new ConstraintViolationsHandler())
.build();
}
Most helpful comment
Validation is not enabled by default by
@WebMvcTest(slice tests switch off auto-config and only enables a few of them explicitly). I guess we could add it to the list for@WebMvcTest.