如何使用Spring WS和JAXB

时间:2017-04-28 18:05:52

标签: spring-boot jaxb spring-ws

我试图从我无法控制的SOAP服务中提取数据。层次结构包含ProductOrder - > ShipTo - >每个shipto有一个或多个shipToes和一个或多个Items的项目。

他们的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] at   org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760)   〜[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] at   org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747)   〜[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] at   org.springframework.boot.SpringApplication.run(SpringApplication.java:315)   〜[spring-boot-1.5.0.RELEASE.jar:1.5.0.RELEASE] at   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] at   edu.umich.oud.giftformatter.convioexport.CustJaxbUnMarshaller.unmarshal(CustJaxbUnMarshaller.java:37)   〜[classes /:na] at   org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   org.springframework.ws.client.core.WebServiceTemplate $ 3.extractData(WebServiceTemplate.java:413)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:619)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)   〜[spring-ws-core-2.4.0.RELEASE.jar:2.4.0.RELEASE] at   edu.umich.oud.giftformatter.convioexport.services.ConvioClient.queryInternal(ConvioClient.java:159)   〜[classes /:na] at   edu.umich.oud.giftformatter.convioexport.services.ConvioClient.query(ConvioClient.java:134)   〜[classes /:na] at   edu.umich.oud.giftformatter.convioexport.services.ProductOrderService.getProductOrders(ProductOrderService.java:87)   〜[classes /:na] at   edu.umich.oud.giftformatter.convioexport.services.ConvioService.load(ConvioService.java:82)   〜[classes /:na] at   edu.umich.oud.giftformatter.convioexport.Application.lambda $亚军$ 0(Application.java:72)   〜[classes /:na] at   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与记录的架构定义不匹配   类型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");
}

1 个答案:

答案 0 :(得分:0)

似乎有两个问题导致这种情况无效:

  1. 子对象的错误字段定义。 shipTo.items vs shipTo.Items
  2. 禁用marshaller / unmarshaller中的dtd验证