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

多个JsonCreator注释方法

  •  5
  • Menelaos  · 技术社区  · 7 年前

    初始问题

    @JsonCreator 方法,对于jackson来说,根据方法定义来检测应该使用哪种方法?

    @JsonCreator
    public static StateOfComm factory(String id) {
        return StateOfComm.valueOf(id);
    }
    
    @JsonCreator
    public static StateOfComm factory(CustomType value) {
        return StateOfComm.valueOf(value.getId());  
    }
    

    使现代化

    失败的JSON(因为id=null)如下所示:

    {"comment":null, "processes":[{"stateOfComm":{"id":"CA"}}]}
    

     {"comment":null, "processes":[{"stateOfComm":"CA"}]}
    
    3 回复  |  直到 7 年前
        1
  •  3
  •   Manos Nikolaidis    7 年前

    我能够通过以下方式解析您问题中的两个JSON示例:

    1. 使用 jackson-modules-java8 版本2.9.1依赖关系
    2. 使用调用java 8编译器 -parameters
    3. 为所有涉及的类引入所有参数构造函数
    4. 避免 @JsonProperty 静态创建方法和构造函数
    5. 定义类:

      class CustomType {
          private final String id;
      }
      

    我的理解是,在旧版本中,杰克逊无法区分多个创作者。E、 g.见答案 here 和github问题 here . 在这种情况下,在java 8的编译代码中选择参数名似乎有帮助。

        2
  •  3
  •   Menelaos    5 年前

    我解决了这个问题,摆脱了 @JsonCreator 注释,并使用自定义 StdDeserializer 这就成功了。

    下面是一个示例:

    @JsonIgnoreProperties(
            ignoreUnknown = true
        )
        @JsonDeserialize(
            using = IdTextEntry.Deserializer.class
        )
        @Data
        public class IdTextEntry implements IdAndText {
            String id;
            String text;
    
            public IdTextEntry(Enum<?> val) {
                if (val != null) {
                    this.id = val.name();
                    this.text = val.toString();
                }
    
            }        
    
            public static class Deserializer extends StdDeserializer<IdTextEntry> {
                public Deserializer() {
                    this((Class)null);
                }
    
                Deserializer(Class<?> vc) {
                    super(vc);
                }
    
                public IdTextEntry deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
                    JsonNode node = (JsonNode)jp.getCodec().readTree(jp);
                    String id;
                    if (node.has("id") && node.has("text")) {
                        id = node.get("id").asText();
                        String text = node.get("text").asText();
                        return new IdTextEntry(id, text);
                    } else if (node.has("id")) {
                        id = node.get("id").asText();
                        return new IdTextEntry(id, id);
                    } else {
                        id = node.asText();
                        return new IdTextEntry(id, id);
                    }
                }
            }
        }
    
        3
  •  -1
  •   Yogi    7 年前

    可以有多个@JsonCreator方法,但需要使用@JsonProperty来指定要初始化的属性。

    @JsonCreator
    public static StateOfComm factory(@JsonProperty("id") String id) {
        return StateOfComm.valueOf(id);
    }
    
    @JsonCreator
    public static StateOfComm factory(@JsonProperty("value") CustomType value) {
        return StateOfComm.valueOf(value.getId());  
    }