反序列化JSON值字符串

时间:2016-08-16 14:35:35

标签: java spring-mvc spring-boot jackson

我们正在使用Spring Boot公开一个由dumb客户端调用的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值字符串的事实有关。杰克逊是否提供了任何可用于强制将JSON值字符串反序列化为Data的实例的注释?

1 个答案:

答案 0 :(得分:0)

密钥位于public Builder withData() Message.Builder.class方法中,用于将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
}

希望它有所帮助。