当前位置: 首页 > 知识库问答 >
问题:

用于列表验证的自定义ConstraintValidator

宓和同
2023-03-14

Spring靴2.0.3。发布,javax。验证2.0.1。最后一个选项被使用。

我需要验证进入控制器的请求:

@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);
    }
}

这叫做服务:

@AllArgsConstructor
@Service
@Slf4j
public class QuotasService {
    private QuotasRepository quotasRepository;

    public void insertQuotas(List<Quota> quotaList) {
        quotasRepository.saveAll(quotaList);
    }
}

将对象保存到MongoRepository方法

我也有一个自定义注释:

@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 {};
}

通过以下方式验证:

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;
    }
}

我的目标是验证DTO:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Quota {
    @Id
    private Integer storeId;
    @JsonProperty("quotas")
    private List<QuotaDelivery> quotaDeliveryList;
}

具体来说QuotaDelivery对象里面:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class QuotaDelivery {
    QuotaDeliveryTypeEnum type;
    @JsonProperty("quotasForPaymentTypes")
    @SumOfValuesEqualsToOneHundred
    List<QuotaPayment> quotaPaymentList;
}

相对于QuotaPayments'values的总和等于100。

换句话说,只有那些QuotaPayment中的QuotaDeliveryfromQuotaPayment中的值总共为100的QuotaPayment对象才是有效的。

问题是前面提到的sumofValueSequalTooneHundredValidator被忽略。我的意思是调试模式显示控件从不执行public boolean isValid(列表

我错过了什么?

感谢任何帮助。


共有1个答案

段成益
2023-03-14

使用@Valid in list和@Validated in controller类:

@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;
 类似资料:
  • 问题内容: 我有一个非常简单的表格: 这是自定义表单验证的完成方式吗?我需要评估该电子邮件地址当前没有用户存在。我还需要评估并匹配。我该怎么做呢? 问题答案: 要单独验证单个字段,可以在表单中使用clean_FIELDNAME()方法,因此对于电子邮件: 然后对于相互依赖的共同依赖字段,你可以覆盖在单独验证所有字段(email如上)之后运行的 方法: 我不确定你从哪里来,但是看起来这是为m你的表单

  • 表单验证发生在数据验证之后。如果你需要定制化这个过程,有几个不同的地方可以修改,每个地方的目的不一样。表单处理过程中要运行三种类别的验证方法。它们通常在你调用表单的is_valid() 方法时执行。还有其它方法可以触发验证过程(访问errors 属性或直接调用full_clean() ),但是通用情况下不需要。 一般情况下,如果处理的数据有问题,每个类别的验证方法都会引发ValidationErr

  • 问题内容: 我有一个看起来像这样的表格: 它的设置使得输入数据后所有必填字段和“保存”按钮都可以使用。但是,部分验证是,我将使用输入的数据使用$ http通过POST通过服务器访问服务器。 我应该在函数中放置该逻辑还是有一个更好的放置位置? 更新: * 我实现了以下内容,将其作为元素上的属性应用,但它在每次我不喜欢的按键上调用服务器/数据库: 问题答案: 您不需要在指令中发出$ http请求,更好

  • 我想在spring验证器中创建基于条件的验证。我有一个UserDTO类,因为有两个DTO类带有注释。 如果我传递isPrimary,那么它应该只验证primaryDTO bean,而忽略secondoryDTO验证。 请引导。 谢谢

  • 我正在使用ApacheCXF、Spring和JAX-RS构建一个REST web服务,当输入JSON验证失败时,我需要在其中发送自定义异常。 我没有使用业务逻辑,而是尝试使用CXF、JAX-RS的现成bean验证功能。 Bean验证工作正常,但是,它总是抛出500个异常,这是不太有用的。根据留档,它是org.apache.cxf.jaxrs.validation.ValidationExcepti

  • 我想知道你是否可以使用vee validate插件编写自定义日期验证,其中结束日期不能小于开始日期?我到处寻找,我找不到确切的答案。 如果没有办法实现这一点,那么我可以凑合着没有它,但是,现在我已经在我的模板中实现了我的开始日期是: 我的脚本如下所示: 但是没有出现任何验证。我想我在我的脚本中丢失了一些东西,但我不确定如何将日期实现到那里。任何帮助将不胜感激。