使用SOAP和JSON的Spring集成Web服务

时间:2014-05-02 13:42:10

标签: json soap spring-integration

我是Spring Integration的新手,想知道使用SOAP和JSON有效负载调用服务的最佳方法。我的配置如下所示。我有SOAP流工作,我们支持多个命名空间,所以我使用SI来处理传入的消息,确定版本(从包名称)并将其路由到正确的端点。正如我所提到的,这是有效的。

<int-ws:inbound-gateway id="ContactServiceGateway"
    request-channel="ContactServiceRequestChannel" marshaller="marshaller"
    unmarshaller="marshaller" />

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="packagesToScan">
        <list>
            <value>com.predictivesolutions.schema.v1</value>
            <value>com.predictivesolutions.schema.v2</value>
                    <value>com.predictivesolutions.schema.v3</value>
        </list>
    </property>
</bean>

<!-- map the ContactService endpoint to the Gateway -->
<bean
    class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
    <property name="mappings">
        <props>
            <prop key="http://localhost:8088/ws-inbound-gateway/ContactService">ContactServiceGateway</prop>

        </props>
    </property>
</bean>

<int:channel id="ContactServiceRequestChannel" />


<int:channel id="ContactServiceRequestChannelWithHeaders">
    <int:interceptors>
        <ref bean="SecurityInterceptor" />
    </int:interceptors>
</int:channel>


<!-- REST Configuration -->

<int-http:inbound-gateway id="ContactRestGateway"
    path="*" request-channel="ContactRestRequestChannel" reply-channel="ContactRestResponseChannel"
    supported-methods="GET, POST, PUT, DELETE" reply-timeout="5000"
    header-mapper="headerMapper" request-payload-type="java.lang.String" />

<bean id="headerMapper" class="com.ps.snt.integration.HeaderMapper">
</bean>

<!-- this routes different versions of the SOAP messages to the appropriate 
    channels - we could use annotations of a custom router method instead -->
<int:header-value-router input-channel="ContactServiceRequestChannelWithHeaders"
    header-name="version">
    <int:mapping value="com.predictivesolutions.schema.v1"
        channel="ContactServiceRequestChannel_v1" />
    <int:mapping value="com.predictivesolutions.schema.v2"
        channel="ContactServiceRequestChannel_v2" />
    <int:mapping value="com.predictivesolutions.schema.v3"
        channel="ContactServiceRequestChannel_v3" />
</int:header-value-router>

<!-- create beans all of the different versions -->
<bean id="ContactServiceEndpoint_v1" class="com.ps.snt.integration.ContactServiceEndpoint_v1" />
<bean id="ContactServiceEndpoint_v2" class="com.ps.snt.integration.ContactServiceEndpoint_v2" />
<bean id="ContactServiceEndpoint_v3" class="com.ps.snt.integration.ContactServiceEndpoint_v3" />

<int:service-activator input-channel="ContactServiceRequestChannel_v1"
    ref="ContactServiceEndpoint_v1" />
<int:service-activator input-channel="ContactServiceRequestChannel_v2"
    ref="ContactServiceEndpoint_v2" />
<int:service-activator input-channel="ContactServiceRequestChannel_v3"
    ref="ContactServiceEndpoint_v3" />

我想支持JSON,并尽可能多地重用组件。该流程将处理对/ rest / *的所有传入请求,从HTTP标头确定版本和其他标头值,然后将消息路由到与SOAP调用相同的服务端点。我这样做是通过使用转换器并基本上将JSON字符串转换为版本化的JAXB对象。这也有效。该配置如下所示:

<int-http:inbound-gateway id="ContactRestGateway"
        path="*" request-channel="ContactRestRequestChannel" reply-channel="ContactRestResponseChannel"
        supported-methods="GET, POST, PUT, DELETE" reply-timeout="5000"
        header-mapper="headerMapper" request-payload-type="java.lang.String" />

    <bean id="headerMapper" class="com.ps.snt.integration.HeaderMapper">
    </bean>


    <int:transformer id="ContactRestResponseChannelTransformer"
        ref="transformerBean" input-channel="ContactRestResponseChannel"
        method="toObject" output-channel="ContactRestRequestChannelTransformed" />
    <bean id="transformerBean" class="com.ps.snt.integration.Transformer" />

    <int:channel id="ContactRestRequestChannel" />
    <int:channel id="ContactRestResponseChannel" />
    <int:channel id="ContactRestRequestChannelTransformed" />

    <int:header-value-router input-channel="ContactRestRequestChannelTransformed"
        header-name="version">
        <int:mapping value="com.predictivesolutions.schema.v1"
            channel="ContactServiceRequestChannel_v1" />
        <int:mapping value="com.predictivesolutions.schema.v2"
            channel="ContactServiceRequestChannel_v2" />
        <int:mapping value="com.predictivesolutions.schema.v3"
            channel="ContactServiceRequestChannel_v3" />
    </int:header-value-router>

所以我可以让它工作,但我有其他服务,我最终需要集成,所以我希望尽可能少的配置。一些问题:

  • 我可以只为JSON和SOAP使用一个入站网关吗?我需要 / ContactService和/ rest / ContactService将由此处理 网关。我可以添加一个使用content-type的路由器元素 路由到SOAP流或JSON流。
  • 如何在变压器元件中使用SPeL,如下所示 例。基本上,从标题我可以确定有效载荷的版本,并希望使用内置的杰克逊变换器:

<int:json-to-object-transformer input-channel="ContactRestRequestChannel" type="headers['packageName'].concat('.').concat(headers['version'])"/>

1 个答案:

答案 0 :(得分:1)

您不能在变换器的type属性中使用SpEL。从版本3.0开始,您可以将json__TypeId__标头(变换器的上游)设置为类或完全限定的类名 - 如果变换器上没有type属性,将使用该名称。

正如我在评论中所说;这两个网关使用的技术不同,所以不清楚为什么你认为可以把它们合二为一。

当然,您可以通过普通HTTP使用SOAP,但是您需要解析soap标头等。