Reputation: 1357
Spring Boot 2.0.3.RELEASE, javax.validation 2.0.1.Final are used.
I need to validate a request coming in into a controller:
@RestController
@CrossOrigin
@RequestMapping("/quotas/")
@AllArgsConstructor
@Slf4j
public class QuotasController {
private QuotasService quotasService;
@ApiOperation("Post quotas")
@PostMapping(value = "/quotas", produces = MediaType.APPLICATION_JSON_VALUE)
public void quotas(@Valid @RequestBody List<Quota> quotaList){
quotasService.insertQuotas(quotaList);
}
}
Which calls a service:
@AllArgsConstructor
@Service
@Slf4j
public class QuotasService {
private QuotasRepository quotasRepository;
public void insertQuotas(List<Quota> quotaList) {
quotasRepository.saveAll(quotaList);
}
}
Which saves the objects into MongoRepository method <S extends T> List<S> saveAll(Iterable<S> var1)
.
Also I have a custom annotation:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy =
SumOfValuesEqualsToOneHundredValidator.class)
public @interface SumOfValuesEqualsToOneHundred {
String message() default "Sum of fields doesn't equal to 100";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Which is validated by:
public class SumOfValuesEqualsToOneHundredValidator implements
ConstraintValidator<SumOfValuesEqualsToOneHundred, List<QuotaPayment>>
{
@Override
public void initialize(SumOfValuesEqualsToOneHundred sumOfValuesEqualsToOneHundred) {
//nothing to do
}
@Override
public boolean isValid(List<QuotaPayment> quotaPaymentList,
ConstraintValidatorContext context) {
return quotaPaymentList
.stream()
.mapToDouble(QuotaPayment::getValue)
.sum() == 100;
}
}
My aim is to validate DTO:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Quota {
@Id
private Integer storeId;
@JsonProperty("quotas")
private List<QuotaDelivery> quotaDeliveryList;
}
Specifically QuotaDelivery objects inside:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class QuotaDelivery {
QuotaDeliveryTypeEnum type;
@JsonProperty("quotasForPaymentTypes")
@SumOfValuesEqualsToOneHundred
List<QuotaPayment> quotaPaymentList;
}
Against equality of sum of QuotaPayments
' value
s to 100.
Another words, only those Quota
objects are valid, whose values from QuotaDelivery
from QuotaPayment
give 100 in total.
The problem is forementioned SumOfValuesEqualsToOneHundredValidator
is been ignored. I mean debug mode shows that control never executes public boolean isValid(List<QuotaPayment> quotaPaymentList, ConstraintValidatorContext context)
method.
What did I miss?
Any help is appreciated.
Upvotes: 2
Views: 1977
Reputation: 9437
Use @Valid inside list and @Validated in controller class:
@RestController
@CrossOrigin
@RequestMapping("/quotas/")
@AllArgsConstructor
@Slf4j
@Validated
public class QuotasController {
private QuotasService quotasService;
@ApiOperation("Post quotas")
@PostMapping(value = "/quotas", produces = MediaType.APPLICATION_JSON_VALUE)
public void quotas(@Valid @RequestBody List<Quota> quotaList){
quotasService.insertQuotas(quotaList);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Quota {
@Id
private Integer storeId;
@JsonProperty("quotas")
private List< @Valid QuotaDelivery> quotaDeliveryList;
}
List< @Valid QuotaPayment> quotaPaymentList;
Upvotes: 2