Joshua Burns
Joshua Burns

Reputation: 165

Setting header values in a gateway

Below is my current coinfiguration for our web service. For each service, I create a separate gateway and header-enricher, so I can add a header that tells the router which service to route to. I have omitted some configuration for brevity. I also understand that this can be done with another flow - however there are some other working parts (like versioning, deprecation, etc.) so I need to set it up this way and have a custom router later in the flow.

<bean
        class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
        <property name="mappings">
            <props>
                <!-- TODO use config property for host -->
                <prop key="${service.endpoint.url}/SNTWS/service/CompanyService">SOAPCompanyGateway</prop>
                <prop key="${service.endpoint.url}/SNTWS/service/ContactService">SOAPContactGateway</prop>

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

    <!-- define gateways for each service endpoint -->

    <int-ws:inbound-gateway id="SOAPCompanyGateway"
        request-channel="SOAPCompanyRequestChannel" marshaller="SOAPMarshaller"
        unmarshaller="SOAPMarshaller" />

    <int-ws:inbound-gateway id="SOAPContactGateway"
        request-channel="SOAPContactRequestChannel" marshaller="SOAPMarshaller"
        unmarshaller="SOAPMarshaller" />

    <bean id="SOAPMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPaths">
            <list>
                <!-- list all schema versions that we wish to accept -->
                <value>com.predictivesolutions.schema.v1_1</value>
                <value>com.predictivesolutions.schema.v2_0</value>
            </list>
        </property>
    </bean>


    <!-- these header enrichers add the service header and send all the messages 
        to the same output channel, add specific service headers in this section 
        before all messages are placed on a common channel. THe values of the header 
        must match the service-activator input-channel -->

    <int:header-enricher input-channel="SOAPContactRequestChannel"
        output-channel="SOAPRequestChannel">
        <int:header name="service" value="ContactService" />
    </int:header-enricher>

    <int:header-enricher input-channel="SOAPCompanyRequestChannel"
        output-channel="SOAPRequestChannel">
        <int:header name="service" value="CompanyService" />
    </int:header-enricher>

    <!-- set another header with the package name, which is used to determine 
        version. THis is necessary (along with service header) to route messages 
        to the appropriate versioned service. This code is the same regardless of 
        service type. -->
    <int:header-enricher input-channel="SOAPRequestChannel"
        output-channel="SOAPRequestChannelWithHeaders">
        <int:header name="version"
            expression="payload.getClass().getPackage().getName().substring(payload.getClass().getPackage().getName().lastIndexOf('.')+1)" />
    </int:header-enricher>

The reason I need a separate gateway and header enricher is so I can set the appropriate service header on the message. All messages will be placed on the SOAPRequestChannel, where I get the version.

Ideally, to lessen the configuration, I would like to have one gateway for all endpoint mappings. I could set the header from the URL, since I know that the last part is the service name.

I am looking for ideas to do this. Can I use Spel to access the URL path?

Upvotes: 0

Views: 1331

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121552

Yes, you can do that using an URI:

<int:header-enricher>
    <int:header name="uri" 
      expression="T(org.springframework.ws.transport.context.TransportContextHolder).transportContext.connection.uri" />
</int:header-enricher>

Having that you can do the routing based on that uri value, and even can get rid of those two <int-ws:inbound-gateway> and <int:header-enricher>s, respectively.

Upvotes: 1

Related Questions