Spring Boot 中的 DTO 验证不起作用

发布于 2025-01-11 06:01:45 字数 1442 浏览 0 评论 0原文

我有一个带有 POST 方法的控制器:

        @RestController
        @RequestMapping(value = "/creditDetails", produces = MediaType.APPLICATION_JSON_VALUE)
        @RequiredArgsConstructor
        @Validated
        public class CreditDetailsController {
       
            @ResponseStatus(HttpStatus.CREATED)
            @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
            public CreditDetailsResponse createCreditDetails(@RequestBody @Valid CreditDetailsRequestWithoutId request) {
                return CreditDetailsResponse.convertToResponse(creditDetailsService.createCreditDetails(request));
            }
    }

和 DTO:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreditDetailsRequestWithoutId {
    @DecimalMax("10_000_000")
    private BigDecimal creditLimit;
    @DecimalMin("0")
    @DecimalMax("20")
    private BigDecimal creditPercent;
    private UUID bankId;
}

当我以 111% 传递 CreditDetailsWithoutId 实例时,我没有收到任何错误。为什么我的验证不起作用? 如果重要的话我使用

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.6.3</version>
        </dependency>

“没问题”

I have a controller with POST method:

        @RestController
        @RequestMapping(value = "/creditDetails", produces = MediaType.APPLICATION_JSON_VALUE)
        @RequiredArgsConstructor
        @Validated
        public class CreditDetailsController {
       
            @ResponseStatus(HttpStatus.CREATED)
            @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
            public CreditDetailsResponse createCreditDetails(@RequestBody @Valid CreditDetailsRequestWithoutId request) {
                return CreditDetailsResponse.convertToResponse(creditDetailsService.createCreditDetails(request));
            }
    }

And DTO:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreditDetailsRequestWithoutId {
    @DecimalMax("10_000_000")
    private BigDecimal creditLimit;
    @DecimalMin("0")
    @DecimalMax("20")
    private BigDecimal creditPercent;
    private UUID bankId;
}

When I pass the CreditDetailsWithoutId instance with 111 percent I don't get any errors. Why my validation didn't work?
If it matter i use

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.6.3</version>
        </dependency>

no problem

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

久而酒知 2025-01-18 06:01:45

尝试将十进制值传递给@DecimalMin、@DecimalMax:

@DecimalMax:字段或属性的值必须是小于或等于值元素中的数字的十进制值。 参考

@DecimalMin("0.0")
@DecimalMax("20.0")
private BigDecimal creditPercent;

稍后编辑: 删除 @Data 并添加基本吸气剂和设置者解决了我这边的问题,希望它有效。

// @Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreditDetailsRequestWithoutId {

    @DecimalMax("1E+7")
    private BigDecimal creditLimit;

    @DecimalMin("0.0")
    @DecimalMax("20.0")
    private BigDecimal creditPercent;

    public BigDecimal getCreditPercent(){
        return creditPercent;
    }

    public void setCreditPercent(BigDecimal creditPercent){
        this.creditPercent = creditPercent;
    }

    public BigDecimal getCreditLimit(){
        return creditLimit;
    }

    public void setCreditLimit(BigDecimal creditLimit){
        this.creditLimit = creditLimit;
    }
}

Try to pass a decimal value to @DecimalMin, @DecimalMax,:

@DecimalMax: The value of the field or property must be a decimal value lower than or equal to the number in the value element. reference

@DecimalMin("0.0")
@DecimalMax("20.0")
private BigDecimal creditPercent;

Later edit: Removing @Data and adding basic getters & setters fixed the problem on my side, hope it works.

// @Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class CreditDetailsRequestWithoutId {

    @DecimalMax("1E+7")
    private BigDecimal creditLimit;

    @DecimalMin("0.0")
    @DecimalMax("20.0")
    private BigDecimal creditPercent;

    public BigDecimal getCreditPercent(){
        return creditPercent;
    }

    public void setCreditPercent(BigDecimal creditPercent){
        this.creditPercent = creditPercent;
    }

    public BigDecimal getCreditLimit(){
        return creditLimit;
    }

    public void setCreditLimit(BigDecimal creditLimit){
        this.creditLimit = creditLimit;
    }
}

时常饿 2025-01-18 06:01:45

我刚刚调用了 maven clean install 并开始了验证

I've just called maven clean install and validation started

柳絮泡泡 2025-01-18 06:01:45

对于我的工作:

pom.xml:

   <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.1.Final</version>
        </dependency>

控制器:

    @Slf4j
@RestController
@RequestMapping("/api/v1/auth")
public class AuthHubController {
    @PostMapping("/authenticate")
        public ResponseEntity<?> authenticate(HttpServletRequest request, @Validated @RequestBody AuthRequestDto authRequestDto) {
    
    }

Dto:

public class AuthRequestDto {
    @Pattern(regexp = "\\d{16}", message = "Card number must contain exactly 16 digits")
    String cardNumber; //card number
    }

完全@Validated

for my work this:

pom.xml:

   <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>8.0.1.Final</version>
        </dependency>

Controller:

    @Slf4j
@RestController
@RequestMapping("/api/v1/auth")
public class AuthHubController {
    @PostMapping("/authenticate")
        public ResponseEntity<?> authenticate(HttpServletRequest request, @Validated @RequestBody AuthRequestDto authRequestDto) {
    
    }

Dto:

public class AuthRequestDto {
    @Pattern(regexp = "\\d{16}", message = "Card number must contain exactly 16 digits")
    String cardNumber; //card number
    }

exactly @Validated

空心空情空意 2025-01-18 06:01:45

您必须在控制器类中添加 EExceptionHandler:

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;


@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
    Map<String, String> errors = new HashMap<>();
    ex.getBindingResult().getAllErrors().forEach((error) -> {
        String fieldName = ((FieldError) error).getField();
        String errorMessage = error.getDefaultMessage();
        errors.put(fieldName, errorMessage);
    });
    return errors;
}

You must add EexceptionHandler in your controller class:

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;


@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
    Map<String, String> errors = new HashMap<>();
    ex.getBindingResult().getAllErrors().forEach((error) -> {
        String fieldName = ((FieldError) error).getField();
        String errorMessage = error.getDefaultMessage();
        errors.put(fieldName, errorMessage);
    });
    return errors;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文