Marian
Marian

Reputation: 351

Spring Boot method validation

Problem

I have the following constraints on userUuid and itemUuid:

I tried to implement the validation in my controller like:

@RestController
@Validated // (1)
public class CartItemController {

    @PostMapping("/me/carts/{itemUuid}")
    @ResponseStatus(HttpStatus.CREATED)
    public void addItem(@PathVariable("itemUuid") String itemUuid,
                        Authentication auth) {
        CartItemId id = getCartItemId(getUserUuidFrom(auth), itemUuid);
        ...
    }

    @Unique // (4)
    public CartItemId getCartItemId(@NotNull @Uuid String userUuid, // (2)
                                    @NotNull @Uuid String itemUuid) { // (3)
        return new CartItemId(userUuid, itemUuid);
    }
    ...
}

@Uuid and @Unique are custom constraints. Method validation is enabled in (1). (2) are the contraints for the user UUID. (3) are the constraints for the item UUID. The unique constraint is applied to the returned CartItemId in (4). However, the parameters and the return value are never validated. Neither for the standard @NotNull constraint nor for my custom constraints. I receive HTTP status 201 Created instead of 400 Bad Request.

What am I doing wrong?

Stuff that works

The following code works for the item UUID:

@RestController
@Validated
public class CartItemController {

    @PostMapping("/me/{itemUuid}")
    @ResponseStatus(HttpStatus.CREATED)
    public void addItem(@PathVariable("itemUuid") @Uuid String itemUuid, // (1)
                        Authentication auth) {
        ...
    }

}

Adding the @Uuid to the path variable parameter works. Values like anInvalidUuid are rejected. I also tested the @Unique constraint in other use cases and it worked perfectly.

What is the difference between addItem() and toId()?

Versions

I am using Java 1.8 and Spring Boot 2.0.0.RELEASE. org.hibernate.validator:hibernate-validator:6.0.7.Final is on my classpath.

Upvotes: 0

Views: 2440

Answers (1)

JB Nizet
JB Nizet

Reputation: 692161

Validation of method arguments is based on AOP: a validating proxy intercepts the method call and validates the argument before delegating (if everything is valid), to the actual method.

You're calling the getCartItemId() method from another method of the same class. So the method call doesn't go through the proxy. Only inter-bean calls can be intercepted.

So, in short, getCartItemId should be in a separate bean, injected into your controller.

Upvotes: 3

Related Questions