I am building a REST API. Its made up of a Resource ( @Controller ) which returns a response 204 even when one of the mandatory field is not present.
I am using Spring 3.1, validation-api (1.1.0.Final) & Hibernate-validator(4.3.0). Not sure if Hibernate-validator plays any role here.
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.0.Final</version>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
I have a spring controller @Controller and a Bean with @Component
@POST
@Consumes(value = {MediaType.APPLICATION_JSON})
@Produces(value = {MediaType.APPLICATION_JSON})
@RequestMapping(method = RequestMethod.POST)
public Response addUserData(@Valid @RequestBody UserData userDataRequest) throws ResourceException {
...
}
My UserData bean has
@Component
public class UserData {
@NotNull(message = "user ID should not be null")
@Min(value = 1, message = "user ID should not be empty")
@Max(value = 20, message = "user ID should have length of more than 20")
@Pattern(regexp="[A-Z][a-z]+", message = "Only Alphanumeric characters allowed")
private String userId;
}
My validations are not getting executed. When I dont pass "userId", there is no error thrown. What am I missing here ?
Maybe passing to your "addUserData" method, a bindingResult Object, so you can test for and retrieve validation errors. here is an example of how to use it : Validation form input
You must have the following about the infrastructure
}
Where
validatorConfig
comes fromAnd finally (I suggest you consider put the error messages in a
.properties
file, such asvalidation.properties
how shown below)Some considerations or suggestions:
@Valid
to@Validated
(see the API for the @Validated)@Component
forUserData
(that represents a kind of entity right?). Remember that for that class each instance is unique and anybean
managed by Spring isSingleton.
.properties
file@POST
,@Consumes
and@Produces
annotations?. They are not in the Spring APIAddition 01 about your comment:
Yes, you must use
@EnableWebMVC
. It indicates to Spring create some special beans internally for the web environment. See the @EnableWebMVC API. Is very important that annotation. Even for Rest I use that annotation.About the Rest annotations, use the Spring annotations. Such as
@RequestMapping
and new 'variations' such as@GetMapping
,@PostMapping
etc.. That annotations contain theproduces
andconsumes
attributes. I have never seen your approach about mixing two sets of annotations from Rest.Addition 02
The
WebMvcConfigurerAdapter
class represents the XML configuration file about all theSpring MVC
infrastructureTherefore for XML
@EnableWebMvc
is equivalent<mvc:annotation-driven/>
<mvc:annotation-driven validator="beanNameValidator" />
where thevalidator
attribute according with the.xsd
says:beanNameValidator
according with my@Bean
seems should belocalValidatorFactoryBean
I ultimately ended up using Jersey Bean Validation, instead of Spring. This is because rest of my code is using Jersey anyways. To make this work I just imported Jersey Bean Validation jar and added a small change to web.xml. Validations are now working.
Thank you @Manual Jordan. I will upvote your answer, since it gave me the right clues.