【问题标题】:Spring Boot request body semi-required fieldsSpring Boot 请求正文半必填字段
【发布时间】:2017-11-11 15:11:46
【问题描述】:

在我们的应用程序中,用户可以根据用户 ID 或屏幕名称编写消息。

class Message {
    public final Long userId;
    public final String screenName;
    public final String text;

    @JsonCreator
    public Message(@JsonProperty(value = "user_id", required = ???) Long userId,
                   @JsonProperty(value = "screen_name", required = ???) String screenName,
                   @JsonProperty(value = "text", required = true) String text) {
        this.userId = userId;
        this.screenName = screenName;
        this.text = text;
    }
}

字段 userId 和 screenName 不能同时是可选的,必须提供一个。

在 Spring Boot 中如何标记它们是半必需的?

【问题讨论】:

  • 半必需是什么意思!至少其中一个应该存在?
  • 是的,其中一个应该在场
  • 您是否使用 json 架构来验证您​​的 json? Json 模式为此类用例提供 (oneOf; anyOf, ...)。
  • 如果您使用的 spring 版本高于或等于 4.1 以及 java8,您可以使用 Optional 类 .. 并在开始业务之前简单地测试 userId 和 screenName

标签: spring spring-mvc spring-boot jackson


【解决方案1】:

这似乎更像是一个验证问题,而不是反序列化。

创建一个验证器,然后将@Valid 放在控制器上的@RequestMapping 中。

在此处查看更多信息: Spring REST Validation Example

【讨论】:

  • 2012 年的文章。你确定吗?
【解决方案2】:

来自 jenkov 教程:

@JsonValue

Jackson 注释 @JsonValue 告诉 Jackson Jackson 应该 不尝试序列化对象本身,而是调用方法 在将对象序列化为 JSON 字符串的对象上。注意 Jackson 将转义返回的字符串中的任何引号 自定义序列化,因此您不能返回例如一个完整的 JSON 目的。为此,您应该改用 @JsonRawValue(请参阅前面的 部分)。

@JsonValue 注解被添加到 Jackson 要执行的方法中 调用将对象序列化为 JSON 字符串。这是一个例子 展示如何使用@JsonValue 注解:

public class PersonValue {

    public long   personId = 0;
    public String name = null;

    @JsonValue
    public String toJson(){
        return this.personId + "," + this.name;
    }

}

要求 Jackson 序列化一个 PersonValue 对象是这样的:

"0,null"

因此,当您尝试转换为 JSON 时,您可以使用 @JsonValue 并在某些字段中忽略或不忽略您的代码

@JsonValue
public String toJson(){
    //ignore fields or include them here
}

【讨论】:

    【解决方案3】:

    只需抛出一个 IllegalArgumentException。最好的情况是反序列化,然后通过验证器运行,这样您就可以将序列化和域验证的关注点分开。

    class Message {
        public final Long userId;
        public final String screenName;
        public final String text;
    
        @JsonCreator
        public Message(@JsonProperty(value = "user_id", required = false) Long userId,
                       @JsonProperty(value = "screen_name", required = false) String screenName,
                       @JsonProperty(value = "text", required = true) String text) {
            if(userId == null && screenName == null) {
                throw new IllegalArgumentException("userId or screenName must be provided.");
            }
            this.userId = userId;
            this.screenName = screenName;
            this.text = text;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-30
      • 2020-10-18
      • 1970-01-01
      • 2018-07-18
      • 2021-07-15
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 2017-09-24
      相关资源
      最近更新 更多