【问题标题】:How to pull sub, sub objects with Spring WS and JAXB如何使用 Spring WS 和 JAXB 拉取子对象
【发布时间】: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


    【解决方案1】:

    似乎有两个问题导致这不起作用:

    1. 子对象的错误字段定义。 shipTo.items 与 shipTo.Items
    2. 在编组器/解组器中禁用 dtd 验证

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-08
      • 2012-09-28
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      • 2012-09-20
      相关资源
      最近更新 更多