1

I am trying to parse an XML document which I got in a javax.ws.rs.core.Response through a GET API Call made to a javax.ws.rs.client.Client instance. But I get this error as shown below:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.fivetran.integrations.sage_intacct.model.AuditHistory` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('apbill')
 at [Source: (StringReader); line: 1, column: 767] (through reference chain: com.fivetran.integrations.sage_intacct.model.AuditHistoryDataResponse["operation"]->com.fivetran.integrations.sage_intacct.model.AuditHistoryDataResponse$Operation["result"]->com.fivetran.integrations.sage_intacct.model.AuditHistoryDataResponse$Operation$Result["data"]->com.fivetran.integrations.sage_intacct.model.AuditHistoryDataResponse$Operation$Result$Data["audithistory"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1032)
    at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
    at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1373)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:136)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:252)
    at com.fasterxml.jackson.databind.deser.impl.InnerClassProperty.deserializeAndSet(InnerClassProperty.java:90)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:252)
    at com.fasterxml.jackson.databind.deser.impl.InnerClassProperty.deserializeAndSet(InnerClassProperty.java:90)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:252)
    at com.fasterxml.jackson.databind.deser.impl.InnerClassProperty.deserializeAndSet(InnerClassProperty.java:90)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at com.fivetran.integrations.sage_intacct.SageIntacctApi.query(SageIntacctApi.java:95)
    at com.fivetran.integrations.sage_intacct.SageIntacctUpdater.update(SageIntacctUpdater.java:32)
    at com.fivetran.integrations.sage_intacct.SageIntacctService.update(SageIntacctService.java:65)
    at com.fivetran.integrations.sage_intacct.SageIntacctService.update(SageIntacctService.java:11)
    at com.fivetran.core.Service.update(Service.java:112)
    at com.fivetran.scripts.RunMock.lambda$updateCore2$12(RunMock.java:408)
    at com.fivetran.integrations.db.DbTimer.time(DbTimer.java:132)
    at com.fivetran.scripts.RunMock.lambda$updateCore2$13(RunMock.java:404)
    at java.lang.Thread.run(Thread.java:748)

Here is the XML received through the response which, I am trying to parse:

<?xml version="1.0" encoding="UTF-8"?>
<response>
    <control>
        <status>success</status>
        <senderid>****</senderid>
        <controlid>****</controlid>
        <uniqueid>false</uniqueid>
        <dtdversion>3.0</dtdversion>
    </control>
    <operation>
        <authentication>
            <status>success</status>
            <userid>****</userid>
            <companyid>****</companyid>
            <locationid></locationid>
            <sessiontimestamp>2020-03-04T15:34:12+00:00</sessiontimestamp>
            <sessiontimeout>2020-03-05T00:02:11+00:00</sessiontimeout>
        </authentication>
        <result>
            <status>success</status>
            <function>readByQuery</function>
            <controlid>4ea65c74-6f5a-445d-afa4-193ddbc9e0b0</controlid>
            <data listtype="audithistory" count="xxx" totalcount="xxx" numremaining="xxx" resultId="7765623331Xl-KdJcLu-MlRbvnEh3F@AAAAAc4">
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2695</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>04/30/2019 07:50:33</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.142</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2695:CXMf@QsGq23aoxHxufF1fLwAAABI</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2696</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>04/30/2019 07:50:33</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.142</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2696:CXMf@QsGq23aoxHxufF1fLwAAABI</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2697</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>05/01/2019 07:47:48</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.145</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2697:CXMlPI0DRiZxFRyT4zhOG6QAAABA</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2698</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>05/01/2019 07:47:48</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.145</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2698:CXMlPI0DRiZxFRyT4zhOG6QAAABA</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2703</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>05/13/2019 07:54:51</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.143</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2703:CXNkiyNsWQ4t5uGiof1TQpQAAABQ</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2711</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>05/31/2019 08:32:35</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.144</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2711:CXPDmoVV1YLVGVrbHHkQXoAAAAAY</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2712</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>05/31/2019 08:32:35</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.144</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2712:CXPDmoVV1YLVGVrbHHkQXoAAAAAY</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2713</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>06/01/2019 07:43:35</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.140</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2713:CXPIspoYfO8BxtOLDz7eNZgAAAAk</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
                <audithistory>
                    <OBJECTTYPE>apbill</OBJECTTYPE>
                    <OBJECTKEY>2714</OBJECTKEY>
                    <USERID>admin</USERID>
                    <ACCESSTIME>06/01/2019 07:43:36</ACCESSTIME>
                    <ACCESSMODE>Create</ACCESSMODE>
                    <WORKFLOWACTION></WORKFLOWACTION>
                    <IPADDRESS>192.168.3.140</IPADDRESS>
                    <SOURCE>system</SOURCE>
                    <NOTES></NOTES>
                    <ID>apbill:2714:CXPIspoYfO8BxtOLDz7eNZgAAAAk</ID>
                    <ACTION_DETAILS></ACTION_DETAILS>
                </audithistory>
            </data>
        </result>
    </operation>
</response>

The POJOs which I have made in order to map the above XML.

AuditHistory.java

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "audithistory")
public class AuditHistory {
    public String OBJECTTYPE;
    public String OBJECTKEY;
    public String USERID;
    public String ACCESSTIME;
    public String ACCESSMODE;
    public String WORKFLOWACTION;
    public String IPADDRESS;
    public String SOURCE;
    public String NOTES;
    public String ID;
    public String ACTION_DETAILS;
}

AuditHistoryDataResponse.java

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import java.util.List;

@JacksonXmlRootElement(localName = "response")
public class AuditHistoryDataResponse {
    public Control control;
    public Operation operation;

    public class Control
    {
        public String status;
        public String senderid;
        public String controlid;
        public String uniqueid;
        public String dtdversion;
    }

    public class Operation
    {
        public Authentication authentication;
        public Result result;

        public class Result
        {
            public String status;
            public String function;
            public String controlid;
            public Data data;

            public class Data
            {
                @JacksonXmlProperty(isAttribute = true)
                public String listtype;

                @JacksonXmlProperty(isAttribute = true)
                public String count;

                @JacksonXmlProperty(isAttribute = true)
                public String totalcount;

                @JacksonXmlProperty(isAttribute = true)
                public String numremaining;

                @JacksonXmlProperty(isAttribute = true)
                public String resultId;

                public List<AuditHistory> audithistory;
            }
        }

        public class Authentication
        {
            public String status;
            public String userid;
            public String companyid;
            public String locationid;
            public String sessiontimestamp;
            public String sessiontimeout;
        }
    }
}

Code to make the API call and receive the response

    public void query(SageIntacctEndpoint endpoint) {
        MultivaluedMap<String, Object> headerParams = new MultivaluedHashMap<>();

        headerParams.add("Accept", "application/xml");
        headerParams.add("Content-Type", "application/xml");

        //POJO that is used as the data that is passed as a part of the cURL request
        DataRequest request = setupDataRequestPayload(endpoint);
        try {
            // MAPPER is the XmlMapper object
            String XML = MAPPER.writeValueAsString(request);

            Response response =
                    HTTP.target(API_URL)
                            .request(MediaType.APPLICATION_XML_TYPE)
                            .headers(headerParams)
                            .post(Entity.entity(XML, MediaType.APPLICATION_XML_TYPE));

            AuditHistoryDataResponse xmlObject = MAPPER.readValue(response.readEntity(String.class), AuditHistoryDataResponse.class);

            System.out.println ("Checkpoint");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

A brief explanation of the query Routine: I am executing a cURL request using JAVA and sending XML as a string in the payload section.

The POJOs that I have shown may be different. All of them are public variables, there are no constructors, getters, and setters but they have been working for me so far until now I.e when there are multiple nodes of the same type as shown in the XML.

But what am I missing here? This is the first time I am looking into Jackson. Are there any annotations that I am missing or being wrongly used?

Couple of References that I looked into in an effort this problem:

Pavan Vasan
  • 391
  • 1
  • 9
  • 28
  • 1
    please "try": `@JacksonXmlElementWrapper(useWrapping=false)public List audithistory;` ...though the error message is not straight forward – xerx593 Mar 04 '20 at 16:38
  • @xerx593 I got another error ```com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.fivetran.integrations.sage_intacct.model.AuditHistoryDataResponse$Operation$Result$Data` (although at least one Creator exists): can only instantiate non-static inner class by using default, no-argument constructor```` – Pavan Vasan Mar 04 '20 at 16:43
  • 1
    @PavanVasan Why are all your nested classes "inner classes"? Add `static` to all the nested class declarations, e.g. `public static class Control` – Andreas Mar 04 '20 at 16:46

0 Answers0