杰克逊为什么在我自动生成的POJO枚举中忽略@JsonCreator注释?

时间:2015-07-22 14:36:15

标签: java json enums jackson jsonschema2pojo

像往常一样,我的问题可能是一个非常简单的解决方案:

我有一个 JSON架构片段,用于定义以下枚举:

Elapsed

我公司的框架然后使用jsonschema2pojo和maven在public class ViewModel{ private static System.Timers.Timer aTimer; public ViewModel() { aTimer = new Timer(); aTimer.Interval = 2000; // every two seconds // Hookup to the elapsed event aTimer.Elapsed += DoWork; // Have the timer fire repeated events (true is the default) aTimer.AutoReset = true; // Start the timer aTimer.Enabled = true; } public void DoWork(Object source, System.Timers.ElapsedEventArgs e) { //do work here } } 中创建必要的POJO "title" : { "type": "string", "enum": ["Mr", "Miss", "Mrs", "Ms"], "description": "The person's title" } ,因为TitleClazz的一部分。 JSON模式 - 将clazz作为名称组成 - 将其替换为员工或客户或您喜欢的任何内容:

生成POJO

title

当我运行包含以下内容的请求时:

clazz

我把这个错误抛给了我:

@Generated("org.jsonschema2pojo")
public static enum Title {

    MR("Mr"),
    MISS("Miss"),
    MRS("Mrs"),
    MS("Ms");
    private final String value;
    private static Map<String, Clazz.Title> constants = new HashMap<String, Clazz.Title>();

    static {
        for (Clazz.Title c: values()) {
            constants.put(c.value, c);
        }
    }

    private Title(String value) {
        this.value = value;
    }

    @JsonValue
    @Override
    public String toString() {
        return this.value;
    }

    @JsonCreator
    public static Clazz.Title fromValue(String value) {
        Clazz.Title constant = constants.get(value);
        if (constant == null) {
            throw new IllegalArgumentException(value);
        } else {
            return constant;
        }
    }
}

显然,“先生”在Enum中。

调试时,我可以看到它通过以下类运行(堆栈):

...
  "title" : "Mr",
...

看起来他们 只对Enum的“键”感兴趣 (即常量,例如“com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of com.example.foo.representations.jaxb.Clazz$Title from String value 'Mr': value not one of declared Enum instance names: [Mr, Miss, Mrs, Ms] at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1@1a372b7; line: 4, column: 3] (through reference chain: com.example.foo.representations.jaxb.MySchema["Clazz"]->com.example.foo.representations.jaxb.Clazz["title"]) ”而不是“findEnum():120, EnumResolver (com.fasterxml.jackson.databind.util) deserialize():79, EnumDeserializer (com.fasterxml.jackson.databind.deser.std) “)。我猜测MR注释因某种原因被忽略了。

我知道如何解决这个问题吗? 是否有可能在可能导致此行为的任何位置设置的配置值? (我正在开展一个大型项目;如果我知道我需要寻找什么,我可以搜索代码库;也许是另一个开发人员“错误配置”某个地方......或者问题可能是Mr生活在@JsonCreator?我是否需要抛出Title以获得良好的衡量标准? (如果是这样,到底是怎么回事?)

我们使用的是jackson-core,-annotations和-databind 2.4.2。

更新:我尝试将此作为一个独立的项目,使用以下代码,并且它运行完美 - 这意味着必须有某种设置阻止注释被考虑在内...

Clazz

1 个答案:

答案 0 :(得分:2)

所以,事实证明我们在Spring配置中有以下内容:

<bean id="mapper" class="com.example.foo.jaxb.links.JsonMapper" />
<!-- ... -->
       <jaxrs:providers>
           <bean id="jsonprovider"
                 class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider">
               <constructor-arg ref="mapper" />
               <constructor-arg>
                   <value></value>
               </constructor-arg>
           </bean>
       </jaxrs:providers>

Jsonmapper扩展com.fasterxml.jackson.databind.ObjectMapper,并且主要在其构造函数中设置Jackson设置。然而,我绝望中遗漏的一件事就是这段代码:

// use JAXB annotations (only) 
setAnnotationIntrospector(new JaxbAnnotationIntrospector(
    com.fasterxml.jackson.databind.type.TypeFactory.defaultInstance()));

它几乎完成了它在锡上所说的内容,似乎:它阻止杰克逊评估@JsonCreator@JsonValue注释。一旦杰克逊注释抑制器&#34;一切都好了。

我想要做的是了解它的实际工作原理,所以如果有人有任何有用的链接指向文档/ how-tos /手册/书籍的Spring内容或注释的抑制,那将是非常感激。但与此同时,这解决了我的问题。 :)