com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 无法识别的字段 "user_activity"

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "user_activity"

我的XML长得像

<IDSentrieServiceResponse>
    <session_id>session_number</session_id>
    <service name="IDSentrieUser" version="1.1">
        <action id="IPIDActivityGet">
            <status>0000</status>
            <status_msg>optional msg</status_msg>
            <user_activity_list>
                <username>john</username>
                <user_activity>
                    <time_start>GMT Time</time_start>
                    <time_end>GMT Time</time_end>
                    <user_hostname>John.a10networks.com</user_hostname>
                    <server_ip>192.168.3.249</server_ip>
                    <server_hostname>dcsrvr.a10networks.com</server_hostname>
                    <domain_name>a10.net</domain_name>
                    <dc_name>dc-server-name</dc_name>
                </user_activity>
            </user_activity_list>
        </action>
    </service>
</IDSentrieServiceResponse>

我正在使用 fasterxml-databind 将其放入 Java 对象中。我有一堆 DTO,但它无法创建对象的地方在

public class UserActivityList {

  @JacksonXmlProperty(localName = "username")
  private String userName;

  @JacksonXmlElementWrapper(useWrapping=false, localName = "user_activity")
  private List<UserActivity> userActivity;

  public void setUserActivity(List<UserActivity> userActivity) {
    this.userActivity = userActivity;
  }

  @Override
  public String toString() {
    return "UserActivityList{" +
        "userName='" + userName + '\'' +
        ", userActivity=" + userActivity +
        '}';
  }
}

其中 UserActivity 看起来像

public class UserActivity {

  @JacksonXmlProperty(localName = "time_start")
  private String timeStart;

  @JacksonXmlProperty(localName = "time_end")
  private String timeEnd;

  @JacksonXmlProperty(localName = "user_hostname")
  private String userHostName;

  @JacksonXmlProperty(localName = "server_ip")
  private String serverIp;

  @JacksonXmlProperty(localName = "server_hostname")
  private String serverHostName;

  @JacksonXmlProperty(localName = "domain_name")
  private String domainName;

  @JacksonXmlProperty(localName = "dc_name")
  private String dcName;

  @Override
  public String toString() {
    return "UserActivity{" +
        "timeStart='" + timeStart + '\'' +
        ", timeEnd='" + timeEnd + '\'' +
        ", userHostName='" + userHostName + '\'' +
        ", serverIp='" + serverIp + '\'' +
        ", serverHostName='" + serverHostName + '\'' +
        ", domainName='" + domainName + '\'' +
        ", dcName='" + dcName + '\'' +
        '}';
  }
}

我用它创建对象的方式是

final String responseBody = response.readEntity(String.class);
final ObjectMapper xmlMapper = new XmlMapper();

try {
  final StealthWatchResponse stealthWatchResponse = xmlMapper.readValue(responseBody, StealthWatchResponse.class);
} catch (final IOException e) {
  LOGGER.error("Error in parsing response from Stealthwatch: {}", e);
}

当我 运行 这个时,我得到

550  [main] ERROR c.e.tenant.internal.StealthWatch - Error in parsing response from Stealthwatch: {}
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "user_activity" (class com.project.tenant.internal.response.UserActivityList), not marked as ignorable (2 known properties: "userActivity", "username"])
 at [Source: java.io.StringReader@3059cbc; line: 10, column: 33] (through reference chain: com.project.tenant.internal.response.StealthWatchResponse["service"]->com.project.tenant.internal.response.Service["action"]->com.project.tenant.internal.response.Action["user_activity_list"]->com.project.tenant.internal.response.UserActivityList["user_activity"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:51) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:839) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1045) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1352) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1330) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:264) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.dataformat.xml.deser.WrapperHandlingDeserializer.deserialize(WrapperHandlingDeserializer.java:120) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:101) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2726) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at com.project.tenant.internal.StealthWatch.getUserActivities(StealthWatch.java:36) ~[project-tenant-0.1-SNAPSHOT.jar:na]
    at FetchUserActivity.run(FetchUserActivity.java:34) [project-tenant-0.1-SNAPSHOT.jar:na]
    at FetchUserActivity.main(FetchUserActivity.java:20) [project-tenant-0.1-SNAPSHOT.jar:na]

这里有什么问题?

就我而言

 @JacksonXmlElementWrapper(useWrapping=false, localName = "user_activity")
  private List<UserActivity> userActivity;

localName = "user_activity" 由于某种原因未被兑现。

我的解决方法如下

  @JacksonXmlElementWrapper(useWrapping = false)
  private List<UserActivity> user_activity;

  public void setUser_activity(final List<UserActivity> user_activity) {
    this.user_activity = user_activity;
  }

命名约定不是我想要的,但我会活下去

我知道这已经有几年了,但我 运行 遇到了类似的问题,但想保留 Java 中的命名约定。

组合两个注释 @JacksonXmlProperty@JacksonXmlElementWrapper 似乎可行。

您给出的示例将如下所示:

    ...

    @JacksonXmlProperty(localName = "user_activity")
    @JacksonXmlElementWrapper(useWrapping=false)
    private List<UserActivity> userActivity;

    ...

或者,我还发现 @JsonProperty 注释也有效。在 this tutorial 中用作示例。但是,我发现它在 XML(反)序列化的上下文中有点误导。但这就是它的样子:

    ...

    @JsonProperty("user_activity")
    @JacksonXmlElementWrapper(useWrapping=false)
    private List<UserActivity> userActivity;

    ...

希望这会有所帮助,很不幸 localName@JacksonXmlElementWrapper 注释中被忽略了,但我没有深入研究它。