代码之家  ›  专栏  ›  技术社区  ›  Lewis

使用com.jackson从JSON字符串获取Java对象的最佳方法。?

  •  1
  • Lewis  · 技术社区  · 8 年前

    String string = "[0, [1, 2], [3, 4]]" . 它表示窗体的数据 [ channelID, [price, amount], [price, amount] ... [price, amount]]

    我的最终目标是把这个字符串变成 ChannelObject { channel: 0, data: [PriceObject { price: 1, amount: 2 }, PriceObject { price: 3, amount: 4 }] } .

    Jackson的原生objectMapper在试图将未封装的JSON数组的值读取到一个类时抛出错误,我找到的唯一解决方案是向objectMapper解析器提供字符串 { "data": %s } ,替换原始JSON,并使用带有属性的类 @JsonProperty ArrayNode data

    为“裸”JSON数组编写反序列化程序是最聪明的方法吗?有没有一个更简单的解决办法我错过了?

    非常感谢您的回复。

    ObjectMapper不工作。

    public static void main(String args[]) {
        String input = "[17847,[5391.9,0,-1]";
        ObjectMapper mapper = new ObjectMapper();
        List<ChannelData> list = mapper.readValue(input, ChannelData[].class);
    }
    
    public class ChannelData {
        private int channel;
    
        private List<Data> data;
    
        public ChannelData(int channel, List<Data> data) {
            this.channel = channel;
            this.data = data;
        }
    
        public int getChannel() {
            return channel;
        }
    
        public void setChannel(int channel) {
            this.channel = channel;
        }
    
        public List<Data> getData() {
            return data;
        }
    
        public void setData(List<Data> data) {
            this.data = data;
        }
    }
    
    public class Data {
        private BigDecimal price;
    
        private int count;
    
        private BigDecimal amount;
    
        public Data() {
        }
    
        public Data(BigDecimal price, int count, BigDecimal amount) {
            this.price = price;
            this.count = count;
            this.amount = amount;
        }
    
        public BigDecimal getPrice() {
            return price;
        }
    
        public void setPrice(BigDecimal price) {
            this.price = price;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public BigDecimal getAmount() {
            return amount;
        }
    
        public void setAmount(BigDecimal amount) {
            this.amount = amount;
        }
    }
    

    Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `co.myproject.Application$ChannelData` (no Creators, like default construct, exist): no int/Int-argument constructor/factory method to deserialize from Number value (17847)
     at [Source: (String)"[17847,[5391.9,0,-1]]"; line: 1, column: 2] (through reference chain: java.lang.Object[][0])
        at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
        at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451)
        at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027)
        at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:262)
        at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:356)
        at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1324)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:173)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
        at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:195)
        at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:21)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
        at co.myproject.Application.run(Application.java:27)
        at co.myproject.Application.main(Application.java:39)
    
    Process finished with exit code 1
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Ryuzaki L    8 年前

    错误消息清楚地指定在您的系统中没有默认构造函数(它不是参数构造函数) ChannelData 类,在中不创建参数构造函数 班级。

    public ChannelData(int channel, List<Data> data) 信道数据

    public class ChannelData {
          public ChannelData() { // no arg constructor }