java - 为什么 Jackson 在我自动生成的 POJO 枚举中忽略 @JsonCreator 注释?

标签 java json enums jackson jsonschema2pojo

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

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

"title" : {
    "type": "string",
    "enum": ["Mr", "Miss", "Mrs", "Ms"],
    "description": "The person's title"
 }

然后我公司的框架使用jsonschema2pojo和 maven 来创建必要的 POJO(Title 存在于 Clazz 中,因为 title 是 JSON 中 clazz 的一部分架构 - 以 clazz 作为名称 - 将其替换为员工或客户或您喜欢的任何内容):

生成的 POJO

@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;
        }
    }
}

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

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

我收到了这个错误:

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"])

很明显,“Mr”在枚举中。

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

findEnum():120, EnumResolver (com.fasterxml.jackson.databind.util)
deserialize():79, EnumDeserializer (com.fasterxml.jackson.databind.deser.std)

看起来他们只对枚举的“键”感兴趣(即常量,例如“MR”而不是“先生").我猜 @JsonCreator 注释由于某种原因被忽略了。

知道如何解决这个问题吗? 是否有可能在任何地方设置的配置值可能导致此行为? (我正在做一个大项目;如果我知道我需要寻找什么,我可以搜索代码库;也许另一个开发人员在某处“错误配置”了某些东西......)或者问题可能是 Title 住在 Clazz?我是否需要加入一个 @JsonProperty 以备不时之需? (如果是这样,具体是怎样的?)

我们正在使用 jackson-core、-annotations 和 -databind 2.4.2。

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

ObjectMapper mapper = new ObjectMapper(); // create once, reuse
Clazz value = mapper.readValue(new File("resources/data.json"), Clazz.class);

最佳答案

所以,事实证明我们的 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()));

它几乎完全按照包装盒上所说的进行操作,似乎:它阻止 Jackson 评估 @JsonCreator@JsonValue 注释。一旦“Jackson 注释抑制器”消失,一切都很好。

我想做的是了解它实际上是如何工作的,所以如果有人有任何有用的链接到 docs/how-tos/manuals/books 以了解 Spring 的东西或注释的抑制,那将不胜感激.但与此同时,这解决了我的问题。 :)

关于java - 为什么 Jackson 在我自动生成的 POJO 枚举中忽略 @JsonCreator 注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31566291/

相关文章:

ios - 用字典数据填充 UITableView (Swift)

java - @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) 不适用于微服务上下文

node.js - 如何在 Mongoose 中创建和使用枚举

enums - Thrift 默认枚举值

java - JMapper 如何创建从日期到 LocalDateTime 的转换

java - 我在 Scanner.nextInt() 之后输入 Scanner.nextLine() 来使用新行,但它不起作用

java - 创建闰年计划(包括世纪)

c# - Json反序列化和ADO持久化过程中的字符串截断

java - 有没有办法在 Maven 项目中仅使用枚举或接口(interface)创建 jar 文件?

java - IE 不加载图像