【问题标题】:Add SoapHeader to a Spring WS Endpoint将 SoapHeader 添加到 Spring WS 端点
【发布时间】:2016-05-10 18:11:11
【问题描述】:

作为 Spring 集成项目的一部分,我有一个 spring ws 端点,我想访问 Soap Header。当我将 SoapHeader 添加到方法参数时,我得到以下异常:

[10/05/16 05:00:05:005 PDT] localhost-startStop-1 调试 springframework.integration.util.MessagingMethodInvokerHelper.doWith(): 方法[公共 com.bstonetech.ptms.integration.model.ws.external.contract.GetContractResponse com.bstonetech.ptms.integration.service.ws.GetContractEndpoint.getContract(com.bstonetech.ptms.integration.model.ws.external.contract.GetContractRequest,org.springframework.ws.context.MessageContext) throws java.lang.Exception] 不符合消息处理的条件 不止一种参数类型候选: [@org.springframework.ws.server.endpoint.annotation.RequestPayload com.bstonetech.ptms.integration.model.ws.external.contract.GetContractRequest] 和 [org.springframework.ws.context.MessageContext]。 [10/05/16 05:00:05:005 PDT] localhost-startStop-1 警告 web.context.support.XmlWebApplicationContext.refresh():异常 在上下文初始化期间遇到 - 取消刷新尝试

java.lang.IllegalArgumentException: [class 类型的目标对象 com.bstonetech.ptms.integration.service.ws.GetContractEndpoint] 没有 处理消息的合格方法。

使用 MessageContext messageContext 也会出现同样的错误。

我显然遗漏了一些东西。任何帮助将不胜感激。

整合如下:

   <oxm:jaxb2-marshaller id="contractMarshaller" context-path="com.bstonetech.ptms.integration.model.ws.external.contract"/>
   <ws:inbound-gateway id="getContractWs" request-channel="inboundGetContractChannel" mapped-request-headers="fileId" mapped-reply-headers="fileId"
                       marshaller="contractMarshaller" unmarshaller="contractMarshaller"/>



   <int:service-activator id="contractEndpoint" input-channel="inboundGetContractChannel" ref="getContractEndpoint"/>

端点如下所示:

@Endpoint
public class GetContractEndpoint {

   private static final String NAMESPACE_URI = "http://bstonetech.com/contract";

   @PayloadRoot(namespace = NAMESPACE_URI, localPart = "GetContractRequest")
   @ResponsePayload
   public GetContractResponse getContract(@RequestPayload GetContractRequest request, SoapHeader soapHeader) throws Exception {
.....
}

【问题讨论】:

    标签: spring-integration spring-ws


    【解决方案1】:

    抱歉耽搁了。我们忙于 Spring Integration 4.3.0.RC1 发布 :-)。

    嗯,看起来你错过了一些东西,因此最终产生了各种担忧。

    Spring WS POJO 方法调用 注释(@RequestPayload@PayloadRoot)和特定于 SOAP 的参数注入确实适用于 POJO 情况,当您在服务上有 @Endpoint 并依赖时在@EnableWs 或类似的 Spring WS 机制上。

    另一方面,没错,Spring Integration WS 模块完全基于 Spring WS 项目,但它旨在尽快将所有内容转换为 Spring Integration Messaging 模型。因此&lt;ws:inbound-gateway&gt; 的结果是Message 发送到request-channel="inboundGetContractChannel"。在您的情况下,payload 将根据 JaxB 映射已经解组到您的某些域对象。

    &lt;service-activator&gt; 现在只能处理消息传递基础架构,并且它对 SOAP 一无所知。这是消息传递的一般用途,当您可以切换到完全不同的源(例如 DB),但仍然使用相同的 &lt;service-activator&gt;

    为了满足一些POJO方法调用有一些有用的注解,比如@Payload@Header等等。

    为了保持一致并仍然提供一些 SOAP 信息,AbstractWebServiceInboundGatewayDefaultSoapHeaderMapper 协商并将source.getSoapHeader() 状态提取为单独的MessageHeaders。因此,您仍然可以从请求中访问所需的标头。

    【讨论】:

    • 谢谢 我现在明白了。我现在使用 PayloadRootQNameEndpointMapping 来映射网关,并将端点简单地实现为 POJO。
    • 您仍然可以这样做并获得下游消息传递的好处。只需将所有“@Endpoint”配置移动到@MessagingGateway 级别
    • 从这里开始,我实现了一个 EnpointInterceptor 来拦截每个入站 Web 服务调用。我在每种情况下都写入数据库并记录成功或错误。我希望能够将创建的数据库表行 ID 传递给 POJO。我看到 MessageContext 具有我可以设置的属性。是否可以在 POJO 执行之前获取到 POJO 中的 MessageContext 或将属性映射到 headers?
    • 首先这是完全不同的问题。从另一面来看,你正在混合担忧。这样的逻辑不应该在拦截器中完成。此模式旨在不影响目标消息。并且从高处将其从流程中移除应该以幂等行为告终。重新考虑逻辑并将insert into DB 逻辑移动到目标@Endpoint。尽管您可以考虑使用ThreadLocal 来存储id 并从您的POJO 中检索它。是的:已经在这里清理了ThreadLocal
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 2014-06-23
    相关资源
    最近更新 更多