【问题标题】:how to map @JsonProperty for an attribute having chance of multiple data types如何为具有多种数据类型的属性映射@JsonProperty
【发布时间】:2018-06-14 11:01:57
【问题描述】:

我使用 jsonProperty annonation 将 json 值映射到 pojo 对象中的变量。

{
  "valueSet": [
   {
     "name": "Type_int",
     "value": 123
   },
   {
     "name": "Type_String",
     "value": "ABC"
   }
  ]
}

对于上面的这个 json,我使用 Object 类对象来捕获“value”属性值。 喜欢

@JsonProperty("value")
private Object value;

这可以很好地捕获“整数”和“字符串”值。

但是对于下面的场景

{
   "valueSet": [
      {
        "name": "Type_int",
        "value": 123
      },
      {
        "name": "Type_String",
        "value": "ABC"
      },
      {
         "name": "Type_array",
         "value": [
            {
              "x": 0,
              "y": 0
            },
            {
              "x": 10,
              "y": 10
            },
            {
              "x": 20,
              "y": 20
            }
            ]
      }
      ]
}

“值”属性有三种不同的数据类型。我不能使用对象来捕获值。那么,有什么方法可以捕获“value”属性中的所有值。

【问题讨论】:

  • 为什么不能使用Object
  • 你可以,但你应该相应地投射它
  • 它不适用于值数组@CassioMazzochiMolin
  • @NiveR,无法转换,它将原始 json 作为字符串返回。
  • 这对于 Jackson 自定义反序列化器来说是一个完美的情况。只需扩展 StdDeserializer 并覆盖 deserialize(...) 方法即可支持您需要的所有三种类型。

标签: java json jackson pojo


【解决方案1】:

试试我的运气,用下面的代码,

public class Value {

    @JsonProperty("name")
    private String name;

    @JsonProperty("value")
    private Object value;

    @JsonProperty("value")
    private ValueObject valueObject;

    //setters and getters
}

ValueSet

public class ValueSet {

    @JsonProperty("valueSet")
    private List<Value> l;

    //setters & getters
}

ValueObject

public class ValueObject {

    @JsonProperty("x")
    private int x;

    @JsonProperty("y")
    private int y;

    //setters & getters
}

以及测试方法

@Test
public void test() {
    String input = "{\"valueSet\":[{\"name\":\"Type_int\",\"value\":123},{\"name\":\"Type_String\",\"value\":\"ABC\"},{\"name\":\"Type_array\",\"value\":[{\"x\":0,\"y\":0},{\"x\":10,\"y\":10},{\"x\":20,\"y\":20}]}]}";
    //String input = "{\"valueSet\":[{\"name\":\"Type_int\",\"value\":123},{\"name\":\"Type_String\",\"value\":\"ABC\"}]}";
    ObjectMapper mapper = new ObjectMapper();
    try {
        ValueSet v = mapper.readValue(input, ValueSet.class);
        System.out.println(v);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

以相反的顺序输出。

ValueSet [l=[Value [name=Type_int, value=123], Value [name=Type_String, value=ABC]]]
ValueSet [l=[Value [name=Type_int, value=123], Value [name=Type_String, value=ABC], Value [name=Type_array, value=[{x=0, y=0}, {x=10, y=10}, {x=20, y=20}]]]]

添加toString() 方法以在log 或控制台中查看输出。不知何故,这对我有用。不确定它是否适合您。

【讨论】:

  • 我试过了,得到了这个问题 Conflicting setter definitions for property "value"
  • 我将 Jackson 2.8.x 作为 JSON 库。
  • 我正在使用 jackson 2.9.x 库。
  • 这次我用 Jackson 2.9.5 库执行了相同的代码,它仍然可以正常工作。我之前有杰克逊 2.8.11.1。当您将 json-annotations 放在 setter 而不是字段上时,会发生您提到的错误。
【解决方案2】:
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("valueSet");
for(int i=0; i<jsonArray.length(); i++) {
    System.out.println(jsonArray.optJSONObject(i).get("value").toString());
}

【讨论】:

  • 您可能想解释一下为什么这是一个答案。这如何解决OP的问题?
猜你喜欢
  • 2023-04-03
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 2019-03-17
  • 2012-09-23
  • 2017-04-04
  • 1970-01-01
相关资源
最近更新 更多