自定义注释未验证方法参数
Custom annotation isn't validating method parameter
我创建了自定义注释
@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 {};
}
像这样的验证器
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;
}
}
我尝试在我的 RestController 中使用它
@RestController
public class CalcApiController extends CalcApi {
@Override
public ResponseEntity<String> calcProfitability(@Valid @CheckGranularity @RequestBody final AssetCostsRequest assetCostsRequest) {
return ResponseEntity.ok("Works");
}
我尝试通过编写测试来使用此注释:
@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);
}
AssetCostsRequest 的相关部分:
public class AssetCostsRequest {
@JsonProperty
@NotNull
private TimeRange range;
@JsonProperty
@NotNull
private Long granularity = 30L;
...getters & setters
}
测试方法 returns 为 200。当我尝试在 isValid
方法中设置断点时,当我 运行 测试时它没有命中。我尝试更改注释的顺序,删除 @Valid
,在 CheckGranularity
class 中更改 @Target
,但没有任何帮助。我正在使用 RestAssured 进行测试。
如何才能使我的注释正确验证参数?
将CheckGranularity
的目标更改为ElementType.TYPE
并直接在AssetCostsRequest
上添加@CheckGranularity
。同时从端点定义中删除 @CheckGranularity
。
它是如何工作的。通过在端点的参数上添加 @Valid
,您告诉 spring 验证它。添加像 @CheckGranularity
这样的验证不会在与 Valid
相同的级别上工作。它必须添加到参数 class 内的某处。
我创建了自定义注释
@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 {};
}
像这样的验证器
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;
}
}
我尝试在我的 RestController 中使用它
@RestController
public class CalcApiController extends CalcApi {
@Override
public ResponseEntity<String> calcProfitability(@Valid @CheckGranularity @RequestBody final AssetCostsRequest assetCostsRequest) {
return ResponseEntity.ok("Works");
}
我尝试通过编写测试来使用此注释:
@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);
}
AssetCostsRequest 的相关部分:
public class AssetCostsRequest {
@JsonProperty
@NotNull
private TimeRange range;
@JsonProperty
@NotNull
private Long granularity = 30L;
...getters & setters
}
测试方法 returns 为 200。当我尝试在 isValid
方法中设置断点时,当我 运行 测试时它没有命中。我尝试更改注释的顺序,删除 @Valid
,在 CheckGranularity
class 中更改 @Target
,但没有任何帮助。我正在使用 RestAssured 进行测试。
如何才能使我的注释正确验证参数?
将CheckGranularity
的目标更改为ElementType.TYPE
并直接在AssetCostsRequest
上添加@CheckGranularity
。同时从端点定义中删除 @CheckGranularity
。
它是如何工作的。通过在端点的参数上添加 @Valid
,您告诉 spring 验证它。添加像 @CheckGranularity
这样的验证不会在与 Valid
相同的级别上工作。它必须添加到参数 class 内的某处。