【问题标题】:How to call Service Activator dynamically in spring Integration如何在spring集成中动态调用Service Activator
【发布时间】:2013-04-22 06:28:39
【问题描述】:

目前在我们的项目中,我们使用的是 spring 框架。由于一些项目需求,我们计划在我们的项目中实现 Spring Integration 框架。

我打算抛出 Spring Integration Sample(Spring Integration Rest HTTP Path Usage Demo) appications

下面是applicationContext-http-int.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd      
    http://www.springframework.org/schema/integration/http http://www.springframework.org/schema/integration/http/spring-integration-http.xsd   
    http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:oxm="http://www.springframework.org/schema/oxm" 
xmlns:int-http="http://www.springframework.org/schema/integration/http">

<int:annotation-config/>

<!-- handler mapping implementation that is aware of inbound Spring Integration 
        http inbound gateway's and inbound adapter's with "path" attributes -->
<bean class="org.springframework.integration.http.inbound.UriPathHandlerMapping"/>

<!-- Inbound/Outbound Channels -->
<int:channel id="employeeSearchRequest" />
<int:channel id="employeeSearchResponse" />


<int-http:inbound-gateway id="inboundEmployeeSearchRequestGateway"      
    supported-methods="GET, POST" 
    request-channel="employeeSearchRequest"
    reply-channel="employeeSearchResponse"      
    mapped-response-headers="Return-Status, Return-Status-Msg, HTTP_RESPONSE_HEADERS"       
    view-name="/employee" 
    path="/services/employee/{id}/search"
    reply-timeout="50000">

    <int-http:header name="employeeId" expression="#pathVariables.id"/>

</int-http:inbound-gateway>


<!-- Note: The default parameter name for favorParameter is 'format'. For instance, when this flag is true, a request for /services/employee/{id}/search?format=json will result 
        in an MappingJacksonJsonView being resolved, while the Accept header can be the browser-defined text/html,application/xhtml+xml  -->

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1" /> 
    <property name="defaultContentType" value="application/xml"/>
    <property name="favorParameter" value="true"/>  
    <property name="ignoreAcceptHeader" value="true" />     
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />             
        </map>
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.integration.samples.rest.json.view.ExtendedMappingJacksonJsonView" >
                <property name="objectMapper" ref="jaxbJacksonObjectMapper"/>
            </bean> 
            <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                <constructor-arg ref="marshaller"/>                 
            </bean>             
        </list>
    </property>             
</bean>

<oxm:jaxb2-marshaller id="marshaller" contextPath="org.springframework.integration.samples.rest.domain" />

<int:service-activator id="employeeServiceActivator" 
                input-channel="employeeSearchRequest"
                output-channel="employeeSearchResponse" 
                ref="employeeSearchService" 
                method="getEmployee" 
                requires-reply="true"  
                send-timeout="60000"/>

<bean id="jaxbJacksonObjectMapper" class="org.springframework.integration.samples.rest.json.JaxbJacksonObjectMapper"/>              

据我了解,流程就像输入通道中有消息时 employeeSearchService 将被激活。 但是根据我们的项目要求,我们需要在运行时根据一些标头值激活服务,例如

  • 如果服务名称 = LoginService 和方法名称 = 操作比 Service Activator 应该激活 LoginService 并调用 action 方法。 基于 url 模式
  • 例如 如果我的 url 类似于 http://ipaddress:8080/myapp/LoginService(is ServiceName).action(is method name),那么应该激活 LoginService 并调用 action 方法。

任何建议和帮助都将不胜感激,因为 SI 对我来说是新的。

【问题讨论】:

    标签: java spring spring-integration


    【解决方案1】:

    有几种方法可以回答这个问题。第一种是使用简单的标头值

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:int="http://www.springframework.org/schema/integration"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd">
    
        <!-- input channel where the message starts -->
        <int:channel id="input.channel"/>
    
        <!-- routes to the different services based on the header value -->
        <int:header-value-router input-channel="input.channel" header-name="serviceName">
            <int:mapping value="a" channel="service.a.channel"/>
            <int:mapping value="b" channel="service.b.channel"/>
        </int:header-value-router>
    
        <!-- when serviceName header == 'a' -->
        <int:channel id="service.a.channel"/>
    
        <int:service-activator input-channel="service.a.channel" ref="serviceA"/>
    
        <!-- when serviceName == 'b' -->
        <int:channel id="service.b.channel"/>
    
        <int:service-activator input-channel="service.b.channel" ref="serviceB"/>
    </beans>
    

    此示例允许您根据您可能需要的不同服务和多个选项进行扩展。

    (input.channel 将与您的 employeeSearchRequest 相同)

    另一个选项使用 SpEL 并假设只有两个服务

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:int="http://www.springframework.org/schema/integration"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd">
    
        <int:channel id="input.channel"/>
    
        <int:service-activator input-channel="input.channel"
            expression="headers['serviceName'] == 'a' ? @serviceA.process(payload) : @serviceB.process(payload)"/>
    
    </beans>
    

    【讨论】:

    • 这适用于 2 个服务,但是如果我有很多服务但只有一个服务激活器和一个输入通道,并且我需要根据 servicename动态调用服务怎么办> 在标题中设置?
    • 在春季论坛上看看这个; forum.springsource.org/…
    • thnx...幸运的是,我一个月前也浏览过该链接并实施了解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    相关资源
    最近更新 更多