我正在尝试解析通过对实例javax.ws.rs.core.Response
进行的 GET API 调用获得的 XML 文档。javax.ws.rs.client.Client
但我收到此错误,如下所示:
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)
这是通过响应收到的 XML,我正在尝试解析:
<?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>
我为映射上述 XML 而制作的 POJO。
审计历史.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;
}
}
}
进行 API 调用和接收响应的代码
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();
}
}
例程的简要说明query
:我正在使用 JAVA 执行 cURL 请求,并将 XML 作为有效负载部分中的字符串发送。
我展示的 POJO 可能会有所不同。它们都是公共变量,没有构造函数、getter 和 setter,但到目前为止它们一直为我工作,即当有多个相同类型的节点时,如 XML 中所示。
但是我在这里错过了什么?这是我第一次关注杰克逊。是否有任何我遗漏或被错误使用的注释?
我在努力解决这个问题时参考了几个参考资料: