【问题标题】:Deserializing JSON-valued string反序列化 JSON 值的字符串
【发布时间】:2016-12-22 23:55:28
【问题描述】:

我们正在使用 Spring Boot 公开一个 REST 端点,该端点由一个哑客户端调用,它为我们提供以下内容:

{
    "timestamp": "2016-08-16T14:30.000Z",
    "data": "{\"amount\":1,\"product\":\"BASIC PRODUCT\"}"
}

我们创建了以下对象:

@JsonDeserialize(builder = Message.Builder.class)
public final class Message {
    private final String timestamp;
    private final Data data;

    public String getTimestamp() {...}
    public Data getData() {...}

    @JsonPOJOBuilder
    public static final class Builder {
        private String timestamp;
        private Data data;

        public Builder withTimestamp(final String timestamp) {...}
        public Builder withData(final Data data) {...}
    }
}

@JsonDeserialize(builder = Data.Builder.class)
public final class Data {
    private final String product;
    private final int amount;

    public String getProduct() {...}
    public int getAmount() {...}

    @JsonPOJOBuilder
    public static final class Builder {
        private String product;
        private int amount;

        public Builder withProduct(final String product) {...}
        public Builder withAmount(final int amount) {...}
    }
}

并将端点暴露为

@RequestMapping(consumes = "application/json", method = POST)
public ResponseEntity<?> receive(@RequestBody Message message) {
   /// ...
}

但控制甚至没有达到receive 方法,并以400 BAD REQUEST 失败。我相信这与 data 是一个 JSON 值的字符串这一事实有关。 Jackson 是否提供任何注释可用于强制将 JSON 值字符串反序列化为 Data 的实例?

【问题讨论】:

  • 您是否尝试将product 字段注释为type,或添加type 字段?可能存在未知/缺失属性的故障?
  • 对不起,我打错了名字。我现在已经纠正了它们。感谢您的关注。
  • 400 BAD REQUEST 响应的正文是否说明了什么有用的信息?是否记录了任何有用的异常?
  • 由于 RequestMapping 有 "consumes = "application/json"",请检查客户端在发送 POST 请求时是否设置了适当的标头。我认为在这种情况下,缺少的标头可以从服务产生 HTTP 400 响应。
  • 您在构建器中的build 方法是什么?

标签: java spring-mvc spring-boot jackson


【解决方案1】:

关键在Message.Builder.classpublic Builder withData()方法中,将JSON值的字符串显式解析为Data类型。将方法参数更改为String而不是Data,并调用ObjectMapper().readValue(JSON-valued string, Data.class)将其反序列化为Data

例如这样:

public Builder withData(final String jsonValue) throws JsonParseException, JsonMappingException, IOException {
    Data data = new ObjectMapper().readValue(jsonValue, Data.class);
    this.data = data;
    return this;
}

为了清楚起见,你是我的全部 POJO:

消息:

public final class Message {
    private final String timestamp;
    private final Data data;

    private Message(Builder builder){
        this.timestamp = builder.timestamp;
        this.data = builder.data;
    }

    public String getTimestamp() {...}
    public Data getData() {...}

    @JsonPOJOBuilder
    public static final class Builder {
        private String timestamp;
        private Data data;

        private static ObjectMapper mapper = new ObjectMapper();

        public Builder withTimestamp(final String timestamp) {
            this.timestamp = timestamp;
            return this;
        }
        public Builder withData(final String jsonValue) throws JsonParseException, JsonMappingException, IOException {
            Data data = mapper.readValue(jsonValue, Data.class);
            this.data = data;
            return this;
        }
        public Message build() {
            return new Message(this);
        }
    } // Builder
}

数据:

public final class Data {
    private final String product;
    private final int amount;

    private Data(Builder builder){
        this.product = builder.product;
        this.amount = builder.amount;
    }

    public String getProduct() {...}
    public int getAmount() {...}

    @JsonPOJOBuilder
    public static final class Builder {
        private String product;
        private int amount;

        public Builder withProduct(final String product) {
            this.product = product;
            return this;
        }
        public Builder withAmount(final int amount) {
            this.amount = amount;
            return this;
        }
        public Data build() {
            return new Data(this);
        }
    } // Builder
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-22
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多