引起:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“状态”

Posted

技术标签:

【中文标题】引起:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“状态”【英文标题】:Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Status" 【发布时间】:2016-10-09 20:19:44 【问题描述】:

我收到以下错误消息,我有 Status 类,但它未被识别。我不知道如何继续,也无法在网上找到答案。

错误

   org.springframework.http.converter.HttpMessageNotReadableException: Could 
   not read JSON: Unrecognized field "Status" (class 
   com.myproject.ticket.EventsResponse), not marked as ignorable (3 known 
   properties: "events", "status", "page"])
      ....
   Caused by: 
   com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 
   Unrecognized field "Status" (class com.myproject.ticket.EventsResponse), 
   not marked as ignorable (3 known properties: "events", "status", "page"])

事件响应

@XmlRootElement(name = "EventsResponse")
@XmlAccessorType(XmlAccessType.FIELD)
public class EventsResponse 
    @XmlElement(name = "Status")
    private Status status;
    @XmlElement(name = "Paging")
    private Page page;
    @XmlElementWrapper(name="Events")
    @XmlElement(name = "Event")
    private List<Event> events;

    .....

状态

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Status 
    @XmlElement(name = "Version")
    private double version;
    @XmlElement(name = "TimeStampUtc")
    private Date timeStampUtc;
    @XmlElement(name = "Code")
    private int code;
    @XmlElement(name = "Message")
    private String message;
    @XmlElement(name = "Details")
    private String details;

回应

<EventsResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Status>
        <Version>2.0</Version>
        <TimeStampUtc>2016-06-11T09:32:21</TimeStampUtc>
        <Code>0</Code>
        <Message>Success</Message>
        <Details />
    </Status>
    <Paging>
        <PageNumber>1</PageNumber>
        <PageSize>50</PageSize>
        <PageResultCount>15</PageResultCount>
        <TotalResultCount>15</TotalResultCount>
        <TotalPageCount>1</TotalPageCount>
    </Paging>
    <Events>
        <Event>

我在 Status 中添加了以下内容,但仍然收到相同的错误。

@XmlElement(name = "Status")
@JacksonXmlProperty(localName = "Status")
private Status status;

【问题讨论】:

您有 XML 的示例吗? @MattPearce 是的,只是包含在问题中。 你能提供整个堆栈跟踪吗 @Haim 我更新了问题,谢谢。 你能指定使用的spring版本吗? 【参考方案1】:

我未能重建您的问题。

我创建了一个测试项目github here,其中包含满足您需求的 Jackson 配置和 JAXB 注释。

我添加了对 jackson-dataformat-xml 和 woodstox-core-asl 的依赖项作为您的 Stax 实现(在我的测试项目中,我使用的是 Jackson 2.6.6.,Spring 4.2.6)

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.6.6</version>
</dependency>
<dependency>
    <groupId>org.codehaus.woodstox</groupId>
    <artifactId>woodstox-core-asl</artifactId>
    <version>4.4.1</version>
</dependency>

将 Jackson2ObjectMapperBuilder 配置为同时使用 Jackson 和 JAXB 注释。这是一个 Spring-boot 示例,用于转换为 Simple Spring-MVC 外观here

@SpringBootApplication
public class EventAppConfiguration 

  public static void main(String[] args) 
       SpringApplication.run(EventAppConfiguration.class, args);
  

  @Bean
  public Jackson2ObjectMapperBuilder jacksonBuilder() 
      Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
      b.indentOutput(true)
      //Enable Introspects for both Jackson and JAXB annotation
     .annotationIntrospector(introspector())
      //Use CamelCase naming
     .propertyNamingStrategy(PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE)
     .dateFormat(new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss"));
      return b;
  
  @Bean
  public AnnotationIntrospector introspector()
     AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
     AnnotationIntrospector secondary = new    JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
     AnnotationIntrospector pair =  AnnotationIntrospector.pair(primary, secondary);
    return pair;
 

注意使用

PropertyNamingStrategy.PASCAL_CASE_TO_CAMEL_CASE

这将使您无需为首字母大写指定替代命名,并且仅需要将 JAXB 注释用于变形和重命名,例如,我的 EventsResponse 将如下所示:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class EventsResponse 
       private Status status;
       @XmlElement(name = "Paging")
       private Page page;
       @XmlElementWrapper(name = "Events")
       @XmlElement(name = "Event")
       private List<Event> events;
    ...

【讨论】:

【参考方案2】:

假设您使用 Jackson 反序列化 XML 对象,您有两个选择。最简单的方法是使用 Jackson 自己的 XML 注释来代替 JAXB @XmlElement 注释。例如:

@XmlElement(name = "Status")
@JacksonXmlProperty(localName = "Status")
private Status status;

@XmlElement 注释位于 Maven 的 jackson-dataformat-xml 包中 - 该版本应与您的其他 Jackson 包版本匹配。)

另一种方法是将 AnnotationIntrospector 注册为反序列化链的一部分 - 即。 (来自单元测试):

    XmlMapper mapper = new XmlMapper();
    AnnotationIntrospector aiJaxb = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
    mapper.setAnnotationIntrospector(aiJaxb);
    // EVENTS_RESPONSE is the incoming XML
    EventsResponse response = mapper.readValue(EVENTS_RESPONSE, EventsResponse.class);

这会识别@XmlElement 注释。例如,如果您需要将其作为 Spring 配置的一部分包括在内,this answer 中有更多详细信息。

(为了使用 JaxbAnnotationIntrospector 类,您需要来自 Maven 的 jackson-module-jaxb-annotation 模块。)

【讨论】:

谢谢,我添加了您建议的注释,但似乎我使用的依赖与您使用的不同。正如 IDE 所说,jacksonXmlProperty 无法解析为类型。为什么我的代码能识别状态?为什么要使用 JacksonXmlProperty? 我添加了一些关于所需依赖项的注释。 Jackson 2.x 不支持开箱即用的默认 JAXB 注释 - 请参阅他们的 wiki 页面 (wiki.fasterxml.com/JacksonJAXBAnnotations) 了解更多详细信息。 我遵循了您的第一个解决方案,但代码仍然返回以下错误。 org.springframework.http.converter.HttpMessageNotReadableException:无法读取 JSON:无法识别字段“状态”(com.myproject.ticket.EventsResponse 类),未标记为可忽略(3 个已知属性:“事件”、“状态”、“页面"]) 问题已更新。 我认为,既然您使用的是 Spring,那么第二个建议更合适。特别是,从链接的答案中添加注释应该会有所帮助(我不使用 Spring,因此无法验证这些注释是否符合需要 - 因此,我不想将它们包含在我的答案中)。 您必须使用模块在对象映射器中注册 jaxbannotationmodule,以便在 jackson2objectmapperfactorbean 中安装功能,以便让 jackson 识别 jaxb 注释。

以上是关于引起:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“状态”的主要内容,如果未能解决你的问题,请参考以下文章

org.codehaus.jackson 与 com.fasterxml.jackson.core

jar包下载地址(fasterxml.jackson)

Azure + SpringBoot 'com/fasterxml/jackson/core/JsonFactory'

fasterxml jackson 的包冲突太垃圾太恶心了: Could not initialize class com.fasterxml.jackson.databind.Seriali...

com.fasterxml.jackson.databind.JsonSerializer 按键排除字段

com.fasterxml.jackson.databind.exc.MismatchedInputException: