Reputation: 427
I created a custom annotation
@Documented
@Constraint(validatedBy = CheckGranularityValidator.class)
@Target( { ElementType.PARAMETER} )
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckGranularity {
String message() default "Duration has to be a multiple of granularity";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
With a validator like so
public class CheckGranularityValidator implements ConstraintValidator<CheckGranularity, AssetCostsRequest> {
@Override
public void initialize(final CheckGranularity constraintAnnotation) {
}
@Override
public boolean isValid(final AssetCostsRequest value, final ConstraintValidatorContext context) {
return value.getRange().getDuration() % value.getGranularity() == 0;
}
}
I tried using it in my RestController
@RestController
public class CalcApiController extends CalcApi {
@Override
public ResponseEntity<String> calcProfitability(@Valid @CheckGranularity @RequestBody final AssetCostsRequest assetCostsRequest) {
return ResponseEntity.ok("Works");
}
I tried using this annotation by writing a test:
@Test
public void calcTest() {
final AssetCostsRequest request = new AssetCostsRequest()
.setRange(new TimeRange(100L, 200L))
.setGranularity(26L);
given()
.contentType(ContentType.JSON)
.body(request)
.when()
.post("/calc")
.then()
.statusCode(HttpStatus.SC_BAD_REQUEST);
}
Relevant part of AssetCostsRequest:
public class AssetCostsRequest {
@JsonProperty
@NotNull
private TimeRange range;
@JsonProperty
@NotNull
private Long granularity = 30L;
...getters & setters
}
Test method returns with 200. When I try to set a breakpoint in isValid
method, it isn't hit when I run the test. I tried changing order of annotations, getting rid of @Valid
, changing @Target
in CheckGranularity
class, nothing helped. I'm using RestAssured for testing.
How do I make it, so my annotation is properly validating a parameter?
Upvotes: 2
Views: 1676
Reputation: 108
Change CheckGranularity
's target to ElementType.TYPE
and add @CheckGranularity
directly on AssetCostsRequest
. Also remove @CheckGranularity
from endpoint definition.
How it works. By adding @Valid
on endpoint's parameter you tell spring to validate it. Adding validation like @CheckGranularity
won't work on the same level as Valid
. It has to be added somewhere inside parameters class.
Upvotes: 2