gpt4 book ai didi

java - @Valid 不适用于嵌套对象(Java/Spring Boot)

转载 作者:行者123 更新时间:2023-12-05 03:47:15 28 4
gpt4 key购买 nike

几天来我一直在尝试在网上找到类似的问题,但似乎找不到任何东西,所以我在这里问我的问题。

我有一个 Controller :

import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Validated
@RestController
@RequestMapping("/data")
public class TheController {

private final TheService theService;

@Autowired
public TheController(TheService theService) {
this.theService = theService;
}

@PostMapping(path = "/data", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.TEXT_PLAIN_VALUE})
public ResponseEntity<String> saveData(@Valid @RequestBody Data data) {
subscriptionDataFeedService.sendData(data.getDataList());
return ResponseEntity.ok()
.body("Data successful.");
}
}

我有请求主体类:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Data {
@NotEmpty(message = "Data list cannot be empty.")
@JsonProperty(value = "dataArray")
List<@Valid DataOne> dataList;
}

我有 DataOne 类:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DataOne {
private @NotBlank String currency;
private @NotBlank String accountNumber;
private @NotBlank String finCode;
private String poNumber;
private @NotBlank String invoiceNumber;
private @NotNull Address billTo;
private @NotNull Address soldTo;
private @NotNull LocalDate invoiceDate;
private @NotBlank String billingPeriod;
private @NotNull LocalDate paymentDueDate;
private @NotNull BigDecimal amountDue;

@JsonProperty(value = "activitySummary")
private @NotNull List<@Valid ProductSummary> productSummaryList;

@JsonProperty(value = "accountSummary")
private @NotNull List<@Valid AccountSummary> accountSummaryList;

@JsonProperty(value = "transactions")
private @NotNull List<@Valid Transaction> transactionList;

private @NotNull PaymentByACH paymentByACH;
private @NotNull Address paymentByCheck;
private @NotNull CustomerServiceContact customerServiceContact;
}

我将包含 Address 类:

import javax.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Address {
private @NotBlank String name;
private @NotBlank String address1;
private String address2;
private @NotBlank String city;
private @NotBlank String state;
private @NotBlank String postalCode;
}

我省略了其他一些类,因为我的问题不需要它们。

所以我遇到的问题是 @Valid 批注能够验证 DataOne 中不是列表的嵌套类的所有内容除外。换句话说,它无法验证 Address、PaymentByACH 等内部的字段。但是,它能够验证这些对象是否为 @NotNull,但无法验证这些类中的字段。

@Valid 无法验证 Address 中的名称、地址 1、城市等字段。每当我在 DataOne 中的地址字段前面添加 @Valid 标记时,我都会收到 HV000028:isValid 调用异常期间出现意外异常。

如何验证 Address 对象或任何嵌套对象中的嵌套字段?

TL;DR: 作为列表的对象,例如 List<@Valid Transaction> transactionList;会验证 Transaction 中的字段,但代码不会验证 Address 中的字段。

最佳答案

好问题。

我认为您稍微误用了 @Valid 注释。

How can I validate the nested fields inside of the Address object orany of the nested objects?

@Valid 不应作为您要验证的字段的前缀。 该工具专门用于验证 @Controller 端点中的参数方法(有时是 @Service 方法)。根据docs.spring.io :

"Spring MVC has the ability to automatically validate @Controllerinputs."

它提供了以下示例,

@Controller
public class MyController {
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(@Valid Foo foo) { /* ... */ }
}

除了在 Controller (或服务)方法的参数中,你应该在任何地方使用 @Valid 的唯一原因是注释复杂类型,如对象列表(即:DataOne:productSummaryList,accountSummaryList,事务列表)。 These docs如果您愿意,可以了解实现您自己的验证政策的详细信息。

为了您的实际需要,您应该只在 Controller 级别的方法和该方法引用的模型的复杂类型上使用 @Valid。然后使用 field-level constraints以确保您不会得到诸如负年龄之类的东西。例如:

@Data
...
public class Person {
...
@Positive
@Max(value = 117)
private int age;
...
}

Check out this list of constraints you can use from the spring docs.您已经在使用 @NotNull 约束,因此这应该不会太陌生。您可以验证电子邮件、信用卡、日期、小数、范围、负值或正值以及许多其他约束。

关于java - @Valid 不适用于嵌套对象(Java/Spring Boot),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64901023/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com