首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Jackson将不同类型反序列化为单个字段

使用Jackson将不同类型反序列化为单个字段
EN

Stack Overflow用户
提问于 2020-09-24 22:03:22
回答 3查看 114关注 0票数 2

我有一个要用来反序列化JSON的如下类

代码语言:javascript
运行
复制
public interface MyObject {

    @JsonProperty("prop")
    String prop;

    @JsonProperty("value")
    Double value();        // Need this to be either a double or a string or a Map
}

但是,我希望能够使用双精度值来解析这两个JSON

代码语言:javascript
运行
复制
{
  prop: "myprop",
  value: 15.7
}

和具有非双精度值的JSON,如字符串或映射

代码语言:javascript
运行
复制
{
  prop: "myprop1",
  value: {
    "attr1": "value1",
    "attr2": 12.0
  }
}

我研究了@JsonSubTypes注释,但它看起来只在涉及继承的情况下有用。有没有可能在杰克逊这样做?如果是这样的话,我如何定义我的Java类来实现同样的目标呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-09-29 16:44:45

一般来说,我不鼓励使用任意类型的数据点。拥有强类型可以带来很多好处,如果你愿意,我可以谈谈这些好处。但是,由于您只谈到了反序列化,所以您可能只是在阅读由其他人生成的JSON。

解决方案很简单:使用对象字段。

代码语言:javascript
运行
复制
public static class MyObject {

    @JsonProperty("prop")
    String prop;

    @JsonProperty("value")
    Object value;        // <- object
}

@Test
public void testUnknownType() throws JsonProcessingException {
    final ObjectMapper objectMapper = new ObjectMapper();
    final MyObject object1 = objectMapper.readValue("{\n" +
        "  \"prop\": \"myprop\",\n" +
        "  \"value\": 15.7\n" +
        "}", MyObject.class);
    Assert.assertEquals(15.7d, object1.value);
    final MyObject object2 = objectMapper.readValue("{\n" +
        "  \"prop\": \"myprop1\",\n" +
        "  \"value\": {\n" +
        "    \"attr1\": \"value1\",\n" +
        "    \"attr2\": 12.0\n" +
        "  }\n" +
        "}", MyObject.class);
    Assert.assertTrue(object2.value instanceof Map);
}
票数 5
EN

Stack Overflow用户

发布于 2020-10-02 22:42:11

你可以这样做:

代码语言:javascript
运行
复制
@JsonDeserialize(using = ExampleDeserializer.class)
public class Example{
String prod;
Object value; /*this field will takes multiple types*/
}

ExampleDeserializer应该是这样的:

代码语言:javascript
运行
复制
public class ExampleDeserializer extends StdDeserializer<Example> {

    public ExampleDeserializer() {
        super(Example.class);
    }

    public ExampleDeserializer(Class<?> vc) {
        super(vc);
    }

@Override
    public Example deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
        Example ex = new Example();
        ObjectCodec mapper = p.getCodec();
        if (mapper == null) mapper = new ObjectMapper();
        JsonNode tree = mapper.readTree(p);
        JsonNode internalNode;

        if (tree.get("prod") != null) {
          internalNode = tree.get("prod");
          prop = internalNode.get("prod").asText();
        }

       if (tree.get("value") != null) {
          internalNode = tree.get("value");
          value = (Double) internalNode.get("value").asDouble() or asText()...;
        }

}
票数 1
EN

Stack Overflow用户

发布于 2020-10-05 21:47:14

如果您使用不同的类型作为不同的名称,那么您将会稍微轻松一些,因此在JSON中应该是:

代码语言:javascript
运行
复制
{
  prop: "my_map_prop",
  mapvalue: {
    "attr1": "value1",
    "attr2": 12.0
  }
}

代码语言:javascript
运行
复制
{
  prop: "my_string_prop",
  stringvalue: "string"
}

如果你这样做,那么你就有了更多的工具来加强有效性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64048165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档