5
votes

I am trying to use Spring Integration (3.0.1) to implement a RESTful service that supports both XML and JSON as request and response formats, using a int-http:inbound-gateway.

My code is based on the Spring integration example (although this does not use the message payload):

https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/rest-http

Service Activator class:

@Service("httpOrderGateway")
public class HttpOrderGateway implements OrderGateway {

    private static final Logger LOGGER = Logger.getLogger(HttpOrderGateway.class);

    @Override
    public Message<CreateOrderResponse> createOrder(Message<CreateOrderRequest> orderRequest) {
        LOGGER.info("Received CreateOrderRequest headers: " + orderRequest.getHeaders());
        LOGGER.info("Received: " + orderRequest.getPayload());

        return MessageBuilder.withPayload(new CreateOrderResponse("Thank you for your order")).build();
    }

}

Spring integration 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.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.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 />  

    <int:channel id="orderRequestChannel" />
    <int:channel id="orderResponseChannel" />

    <int-http:inbound-gateway id="inboundOrderRequestGateway" 
                              supported-methods="POST"
                              request-channel="orderRequestChannel"
                              reply-channel="orderResponseChannel"
                              view-name="/order"
                              path="/services/order"
                              reply-timeout="50000">
    </int-http:inbound-gateway>

    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1" />
        <property name="contentNegotiationManager">
            <bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                <property name="defaultContentType" value="application/json" />
                <property name="mediaTypes">
                    <map>
                        <entry key="json" value="application/json" />
                        <entry key="xml" value="application/xml" />
                    </map>
                </property>
            </bean>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="com.anon.order.gateway.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="com.anon.order.gateway.marshalling.model.impl" />

    <int:service-activator id="orderGatewayActivator"
                               input-channel="orderRequestChannel"
                               output-channel="orderResponseChannel"
                               ref="httpOrderGateway" 
                               method="createOrder" 
                               requires-reply="true"
                               send-timeout="60000" />

    <bean id="jaxbJacksonObjectMapper" class="com.anon.order.gateway.json.JaxbJacksonObjectMapper" />

</beans>

Currently, the code logs out:

Received: <CustomerServiceRequest><CustomerName>Robert Pulson</CustomerName></CustomerServiceRequest>

(or the equivalent JSON format), and returns a response in either JSON or XML, depending on the Accept Header, so that part is working.

I have read the following similar question that is based on a previous version of Spring Integration:

Spring Integration : http:inbound-channel adapter - not getting json object in payload

But this uses an inbound-channel-adaptor, not an inbound-gateway as I have.

How do I configure my inbound-gateway to use the marshaller and jaxbJacksonObjectMapper (from the same configuration file) to convert the raw request body into a CreateOrderRequest instance for both JSON/XML please?

1

1 Answers

2
votes

Configure appropriate HttpMessageConverters and inject them using the message-converters attribute.

See also the merge-with-default-converters attribute.

See MappingJackson2HttpMessageConverter (jackson 2), MappingJacksonHttpMessageConverter (jackson 1.x) and MarshallingHttpMessageConverter.

Also, JAXB and Json message converters are automatically used by default if they are on the classpath. You may be able to just set the request-payload-type on the gateway if conversion doesn't need anything special.

See the reference documentation for more information.