简体   繁体   English

如何使用 lombok 使 DTO 中的字段可选?

[英]How do I make fields in DTO optional using lombok?

So I have a DTO like this,所以我有一个像这样的 DTO,

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other;
}

I am passing the following payload to an external API我将以下有效负载传递给外部 API

{
    "name": "John",
    "phone": "123",
    "address": "abc"
}

This is throwing me 500 internal error:这向我抛出了 500 个内部错误:

HttpClientErrorException$NotFound: 404: "{<EOL> "status": "Error", <EOL> "message": "Error validating JSON. Error: - Invalid type Null, expected String."}"

If I comment out other property in DTO then I will successfully get 200 response.如果我在 DTO 中注释掉other属性,那么我将成功获得 200 响应。 I thought @JsonIgnoreProperties annotation is supposed to ignore the properties that are not present but it seems that's not working.我认为@JsonIgnoreProperties注释应该忽略不存在的属性,但似乎不起作用。

you are using lombok's @NoArgsConstructor and @AllArgsConstructor .您正在使用 lombok 的@NoArgsConstructor@AllArgsConstructor So you have to use one or the other.所以你必须使用其中一个。 If you don't want an all args constructor you'll have to implement your own.如果您不想要一个全参数构造函数,则必须实现自己的。

@NoArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other;

  public PersonDTO(String name, String address, String phone) {
    super(name, address, phone, "");
  }

  public PersonDTO(String name, String address, String phone, String other) {
    this.name = name;
    this.address = address;
    this.phone = phone;
    this.other = other
  }

}

Or if you have control over AND this is a spring boot app, you could try using required=false in your controller so you can continue to use an all arg constructor.或者,如果您可以控制并且这是一个 Spring Boot 应用程序,您可以尝试在控制器中使用required=false ,这样您就可以继续使用全 arg 构造函数。

public PersonDTO getPerson(
      @PathVariable(value = "name") String name,
      @PathVariable(value = "address") String address
      @PathVariable(value = "phone") String phone
      @PathVariable(value = "other", required = false) String other) { 

 ....

}

The error says that they can't parse Null into String .该错误表明他们无法将Null解析为String That's very interesting error and fooled me first.这是一个非常有趣的错误,首先愚弄了我。 Your json object with other field null probably looks like this:您的带有其他字段null的 json 对象可能如下所示:

{
    "name": "John",
    "phone": "123",
    "address": "abc"
}

So somehow this API can't just wrap quotes around null and tells you it's not able to parse this.所以不知何故,这个 API 不能只用引号括住null并告诉你它无法解析它。

Therefore I guess you need to set the value of other to an empty string:因此,我想您需要将other的值设置为空字符串:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
@ToString
@JsonIgnoreProperties(ignoreUnknown=true)
public class PersonDTO {
  private String name;
  private String address;
  private String phone;
  private String other = ""; //empty because external api can't handle null
}

If attributes are nullable then you can use @JsonInclude(Include.NON_NULL) .如果属性可以为空,那么您可以使用@JsonInclude(Include.NON_NULL) This will allow to set null value in the attributes.这将允许在属性中设置空值。 I guess, by default it doesn't allow null value.我猜,默认情况下它不允许空值。

Adding @JsonInclude(JsonInclude.Include.NON_NULL) is the solution as you said in the comment.正如您在评论中所说,添加@JsonInclude(JsonInclude.Include.NON_NULL)是解决方案。 This annotation tells the serializer to ignore fields that are null.此注释告诉序列化程序忽略为空的字段。 If you don't add this the payload will look like this:如果您不添加此内容,则有效负载将如下所示:

{
    "name": "John",
    "phone": "123",
    "address": "abc",
    "other": null
}

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

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