【发布时间】:2017-04-28 18:05:51
【问题描述】:
我正在尝试从我无法控制的 SOAP 服务中提取数据。层次结构包含 ProductOrder -> ShipTo -> Item,其中每个 shipto 有一个或多个 shipToes 和一个或多个 Item。
他们的 API 使用类似 SQL 的模拟查询语言。尝试提取包括项目在内的数据时,我得到如下堆栈跟踪。如果我排除项目,我可以将 ProductOrders 与 ShipTo 对象一起提取,但项目始终是一个空列表。
java.lang.IllegalStateException:无法执行 CommandLineRunner 在 org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779) ~[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] 在 org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) ~[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] 在 org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) ~[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] 在 edu.umich.oud.giftformatter.convioexport.Application.main(Application.java:39) ~[classes/:na] 原因: org.springframework.oxm.UncategorizedMappingException: 未知的 JAXB 例外;嵌套异常是 javax.xml.bind.JAXBException: Field ShipTo.Item.ItemId 的订单与架构定义不匹配 记录类型 ProductOrder at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:915) ~[spring-oxm-4.3.6.RELEASE.jar:4.3.6.RELEASE] 在 edu.umich.oud.giftformatter.convioexport.CustJaxbUnMarshaller.unmarshal(CustJaxbUnMarshaller.java:37) 〜[类/:na]在 org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 org.springframework.ws.client.core.WebServiceTemplate$3.extractData(WebServiceTemplate.java:413) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:619) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383) ~[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] 在 edu.umich.oud.giftformatter.convioexport.services.ConvioClient.queryInternal(ConvioClient.java:159) 〜[类/:na]在 edu.umich.oud.giftformatter.convioexport.services.ConvioClient.query(ConvioClient.java:134) 〜[类/:na]在 edu.umich.oud.giftformatter.convioexport.services.ProductOrderService.getProductOrders(ProductOrderService.java:87) 〜[类/:na]在 edu.umich.oud.giftformatter.convioexport.services.ConvioService.load(ConvioService.java:82) 〜[类/:na]在 edu.umich.oud.giftformatter.convioexport.Application.lambda$runner$0(Application.java:72) 〜[类/:na]在 org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) ~[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] ... 4个常用框架 省略引起:javax.xml.bind.JAXBException:字段顺序为 ShipTo.Item.ItemId 与记录的架构定义不匹配 type ProductOrder ...省略17个常用框架
产品订单服务包含这样一个方法:
public List<ProductOrderObj> getProductOrders(final Date startDate, final Date endDate) {
final String query = String.format("SELECT siteId,orderId,transactionId,purchaseAmount,taxDeductibleValue,\n" +
"shippingCharge,additionalDonation,discountAmount,discountCode,\n" +
"creationDate,createdBy,modifyDate,lastChangeBy,storeId,payment,\n" +
"purchaser,interactionSource,shipTo,\n" +
"receiptNumber,shipTo.item FROM ProductOrder where creationDate > %s and creationDate < %s",
convertDate(startDate), convertDate(endDate));
log.info("query is " + query);
final Session session = convioClient.startSession();
final ArrayList<ProductOrderObj> events = new ArrayList<>();
for (int page = 1; page < 100; page++) {
final List<? extends RecordObj> items = convioClient.query(session, page, ConvioConfiguration.MAX_DOWNLOADS_PER_REQUEST, query);
if (items.size() < ConvioConfiguration.MAX_DOWNLOADS_PER_REQUEST) {
events.addAll((List<ProductOrderObj>) items);
break;
}
events.addAll((List<ProductOrderObj>) items);
}
return events;
}
然后调用 convioService.query 方法来有效地执行此操作
private List<? extends RecordObj> queryInternal(final Session session, final
int page, final int pageSize, final String q) {
// setup query
final Query query = new Query();
query.setPage(BigInteger.valueOf(page));
query.setPageSize(BigInteger.valueOf(pageSize));
query.setQueryString(q);
log.trace(q);
// perform query
try {
final Object obj = getWebServiceTemplate().marshalSendAndReceive(query,
new SoapActionExecutionIdCallback(session));
final QueryResponse response = (QueryResponse) obj;
if (response != null) {
log.debug("Response was a " + response.getClass().getName());
return response.getRecord();
}
} catch (final Exception e) {
log.error(e.getMessage());
throw e;
}
throw new NullPointerException("response was null");
}
【问题讨论】:
标签: spring-boot jaxb spring-ws