JSON consumer of polymorphic objects

前端 未结 2 585
一生所求
一生所求 2020-11-27 08:56

I am parsing JSON and am having difficulty with one structure that can have one of three forms. In my case it could be zero-dimensional, one-dimensional or two-dimensional.

2条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-27 09:04

    Thanks to Eric's comment pointing me to programmerbruce I managed to crack it. Here's the code I used (cut down to simplify).

    public static class Info {
      @JsonProperty("Product")
      public String product;
      // Empty in the 0d version, One entry in the 1d version, two entries in the 2d version.
      @JsonProperty("Dimensions")
      public String[] dimensions;
    
    }
    
    public static class Info0d extends Info {
    }
    
    public static class Info1d extends Info {
      @JsonProperty("Labels")
      public String[] labels;
    }
    
    public static class Info2d extends Info {
      @JsonProperty("Labels")
      public String[][] labels;
    }
    
    public static class InfoDeserializer extends StdDeserializer {
      public InfoDeserializer() {
        super(Info.class);
      }
    
      @Override
      public Info deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        Class variantInfoClass = null;
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = (ObjectNode) mapper.readTree(jp);
        // Inspect the `diemnsions` field to decide what to expect.
        JsonNode dimensions = root.get("Dimensions");
        if ( dimensions == null ) {
          variantInfoClass = Info0d.class;
        } else {
          switch ( dimensions.size() ) {
            case 1:
              variantInfoClass = Info1d.class;
              break;
    
            case 2:
              variantInfoClass = Info2d.class;
              break;
          }
        }
        if (variantInfoClass == null) {
          return null;
        }
        return mapper.readValue(root, variantInfoClass);
      }
    }
    

    And to install this in the ObjectMapper:

    // Register the special deserializer.
    InfoDeserializer deserializer = new InfoDeserializer();
    SimpleModule module = new SimpleModule("PolymorphicInfoDeserializerModule", new Version(1, 0, 0, null));
    module.addDeserializer(Info.class, deserializer);
    mapper.registerModule(module);
    factory = new JsonFactory(mapper);
    

提交回复
热议问题