Search code examples
javaxmldata-bindingjacksonjackson-dataformat-xml

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


My XML looks like

<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>

I am using fasterxml-databind to put this into Java Object. I have bunch of DTOs but the place it fails to create object is in

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 +
        '}';
  }
}

where UserActivity looks like

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 + '\'' +
        '}';
  }
}

the way I use it to create Object is

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

When I run this, I get

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]

What is wrong here?


Solution

  • In my case

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

    localName = "user_activity" was not honored for some reason.

    The way I solved it is following

      @JacksonXmlElementWrapper(useWrapping = false)
      private List<UserActivity> user_activity;
    
      public void setUser_activity(final List<UserActivity> user_activity) {
        this.user_activity = user_activity;
      }
    

    The naming convention is not something I want, but I will live for now