简体   繁体   English

根本没有调用自定义 bean 验证

[英]Custom bean validation is not being called at all

I'm trying to create a custom bean validator, but, no matter what I do, the validator methods are not being called at all.我正在尝试创建一个自定义 bean 验证器,但是,无论我做什么,验证器方法都不会被调用。 All the other validation annotations are working perfectly.所有其他验证注释都运行良好。

This is the annotation:这是注释:

package com.ats.boleta.validation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MaxDateValidator.class)
@Documented
public @interface MaxDate {

    String message() default "Data está acima do máximo permitido.";
    String string();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};    

}

This is the validator:这是验证器:

package com.ats.boleta.validation;

import java.time.LocalDate;
import java.time.temporal.Temporal;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @author Haroldo de Oliveira Pinheiro
 * @see https://gist.github.com/MottoX/e689adf41c22a531af4e18ce285690eb
 */
public class MaxDateValidator implements ConstraintValidator<MaxDate, Temporal> {
    
    private LocalDate maxValue;
    
    @Override
    public void initialize(MaxDate constraintAnnotation) {
        this.maxValue = LocalDate.parse(constraintAnnotation.string());
    }

    @Override
    public boolean isValid(Temporal value, ConstraintValidatorContext context) {
        return value == null || !LocalDate.from(value).isAfter(this.maxValue);
    }
}

This is the main DTO that is being validated:这是正在验证的主要 DTO:

package com.ats.boleta.model.dto;

import java.util.List;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

import com.ats.boleta.model.Boleto;
import com.ats.boleta.model.Cedente;
import com.ats.boleta.model.Titulo;
import com.ats.boleta.validation.PrefixConstraint;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class BoletoDTO {

    @NotBlank(message = "Nome não pode ficar em branco.")
    private String nome;
    
    @PrefixConstraint(message = "Cedente")
    @NotNull(message = "Cedente não pode ficar em branco.")
    private Cedente cedente;
    
    @Valid
    @NotEmpty(message = "Não foi informado nenhum título.")
    private List<Titulo> titulo;
        
}

And this is the child DTO where @MaxDate is being used:这是使用@MaxDate的子 DTO:

(...)
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Titulo {

    @NotBlank(message = "Número do documento não pode ficar em branco.")
    private String numeroDocumento = "";
    
    private Integer nossoNumero;
    
    @NotNull(message = "Carteira não pode ficar em branco.")
    private Integer carteira;
    
    private String valorDocumento = "";
    
    @MaxDate(string = "2099-12-31", message = "Data de vencimento não pode ser posterior a 2099")
    private LocalDate dataVencimento; 
    (...)
    
}

And this is the controller:这是 controller:

package com.ats.boleta.controller;

(...)

@Slf4j
@RestController
@RequestMapping("/v0/boleto")
public class BoletaController {
    (...)

    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
    public ResponseEntity<InputStreamResource> boleto(@Valid @RequestBody BoletoDTO dto) throws IOException {
        (...)
    }

    @RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity<InputStreamResource> remessa(@RequestBody BoletoDTO dto) throws IOException {
        (...)
    }

}

No matter what I do, neither MaxDateValidator.initialize(MaxDate) nor MaxDateValidator.isValid(Temporal, ConstraintValidatorContext) are called, no matter what.无论我做什么,都不会MaxDateValidator.initialize(MaxDate)MaxDateValidator.isValid(Temporal, ConstraintValidatorContext) ,无论如何。 No exception is thrown, no warnings appear in the log, none of the aforementioned methods are called.没有抛出异常,日志中没有出现警告,没有调用上述方法。 All of the other annotations work as intended.所有其他注释都按预期工作。

I have even tried to change the generic on MaxDateValidator to either LocalDate or even Object ;我什至尝试将MaxDateValidator上的泛型更改为LocalDate甚至Object nothing works.没有任何作用。

What could be causing this behavior?什么可能导致这种行为? Is there any way to debug it?有没有办法调试它? Are there any Spring logs that could be activated to check what would be going wrong?是否有任何 Spring 日志可以被激活以检查会出现什么问题?

Can you please try to use:你能尝试使用:

@NotEmpty(message = "Não foi informado nenhum título.")
private List<@Valid Titulo> titulo;

Instead of:代替:

@Valid
@NotEmpty(message = "Não foi informado nenhum título.")
private List<Titulo> titulo;

Please add annotation @Valid for method remessa请为方法remessa添加注释@Valid

package com.ats.boleta.controller;

(...)

@Slf4j
@RestController
@RequestMapping("/v0/boleto")
public class BoletaController {
(...)

@RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<InputStreamResource> boleto(@Valid @RequestBody BoletoDTO dto) throws IOException {
    (...)
}

@RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<InputStreamResource> remessa(@Valid @RequestBody BoletoDTO dto) throws IOException {
    (...)
}

}

In the end, I had forgotten to add the @Valid annotation to the remessa() method on the controller:最后,我忘记在 controller 上的remessa()方法中添加@Valid注解:

package com.ats.boleta.controller;

(...)

@Slf4j
@RestController
@RequestMapping("/v0/boleto")
public class BoletaController {
    (...)

    @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_PDF_VALUE)
    public ResponseEntity<InputStreamResource> boleto(@Valid @RequestBody BoletoDTO dto) throws IOException {
        (...)
    }

    @RequestMapping(value = "/remessa", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE)
    public ResponseEntity<InputStreamResource> remessa(@Valid @RequestBody BoletoDTO dto) throws IOException {
        (...)
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM