JSON到Java POJO无法用于简单结构吗?

时间:2019-03-12 15:34:09

标签: java json jackson

JSON:

@Entity
@ApiModel
public class ServiceType {

    private String id;

    @ApiModelProperty(dataType = "java.lang.String")
    private Service service;
    private String type;

    public Service getService() {
        return service;
    }

    public void setService(Service service) {
        this.service = service;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

Java POJO

{
  "246": {
    "test1": "one" 
  },
  "355": {
    "test2": "two"
  }
}

在我的代码中,我这样做:(使用 Jackson

class POJO{
  private HashMap<String, SubPojo> subMap;

  @JsonAnySetter
  public void addToMap(String key, SubPojo val){ subMap.put(key, value); }
}

class SubPojo{
  private HashMap<String, String> map; 
  @JsonAnySetter
  public void addToMap(String key, String val) { map.put(key, value);}
}

我得到一个例外:

POJO testing = (new ObjectMapper()).convertValue("path/to/json", POJO.class);

我要去哪里错了?

3 个答案:

答案 0 :(得分:0)

类似这样的东西:

public class Pojo {
    private Map<String,Object> map = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, Object value) {
        this.map.put(key, value);
    }

    @JsonAnyGetter
    public Map<String,Object> getMap() {
        return map;
    }
}

有一个article on Baeldung,其中涵盖了Jackson的各种注释,包括该注释以及有关Jackson wiki的一些基础知识。

答案 1 :(得分:0)

converValue方法用于转换对象。参见JavaDoc

  

从给定值进行两步转换的便捷方法,   转换为给定值类型的实例时,如果(但仅当!)转换为   需要。如果给定值已经是请求的类型,则返回值   照原样。此方法在功能上类似于给定的第一次序列化   将值转换成JSON,然后将JSON数据绑定到给定类型的值中,   但应该更有效,因为不需要完全序列化   发生。但是,相同的转换器(序列化器,解串器)将   用于数据绑定,表示相同的对象映射器配置   有效。

例如,您可以像这样将“ File”转换为“ String”:

mapper.convertValue(jsonFile, String.class)

其中jsonFileFile类的实例。结果示例可能是:path/to/json

要对JSON有效负载进行反序列化,请使用readValue方法族中的一个。

您可以使用注释为POJO的构造函数来创建JsonCreator

class Pojo {

    private final Map<String, SubPojo> map;

    @JsonCreator
    public Pojo(Map<String, SubPojo> map) {
        this.map = map;
    }

    public Map<String, SubPojo> getMap() {
        return map;
    }

    @Override
    public String toString() {
        return "Pojo{" +
                "map=" + map +
                '}';
    }
}

class SubPojo {

    private Map<String, String> map;

    @JsonCreator
    public SubPojo(Map<String, String> map) {
        this.map = map;
    }

    @Override
    public String toString() {
        return "SubPojo{" +
                "map=" + map +
                '}';
    }
}

使用简单。要从文件中读取JSON,请使用readValue方法:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        Pojo map = mapper.readValue(jsonFile, Pojo.class);
        System.out.println(map);
    }
}

上面的代码显示:

Pojo{map={246=SubPojo{map={test1=one}}, 355=SubPojo{map={test2=two}}}}

如果您希望保留数据模型,请使用JsonAnySetter批注。您的数据模型可能如下所示:

class Pojo {
    private Map<String, SubPojo> subMap = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, SubPojo value) {
        subMap.put(key, value);
    }

    @Override
    public String toString() {
        return "POJO{" +
                "subMap=" + subMap +
                '}';
    }
}

class SubPojo {
    private Map<String, String> map = new HashMap<>();

    @JsonAnySetter
    public void addToMap(String key, String value) {
        map.put(key, value);
    }

    @Override
    public String toString() {
        return "SubPojo{" +
                "map=" + map +
                '}';
    }
}

上面的使用示例打印:

POJO{subMap={355=SubPojo{map={test2=two}}, 246=SubPojo{map={test1=one}}}}

答案 2 :(得分:0)

您无需创建任何POJO类来解析该JSON文本,因为可以将其解析为Map<String, Map<String, String>>

您将必须使用TypeReference来防止丢失泛型类型参数。

Map<String, Map<String, String>> data = new ObjectMapper()
        .readValue(new File("test.json"),
                   new TypeReference<Map<String, Map<String, String>>>() {});

使用问题中的JSON文本打印data映射将显示:

{246={test1=one}, 355={test2=two}}