Spring Integration - how to send POST parameters with http outbound-gateway

11,090

Thanks to the pointers from @jra077 regarding Content-Type, this is how I solved it.

My SI config now looks like this - the important bit was adding the Content-Type header:

<?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"
   xmlns:int-http="http://www.springframework.org/schema/integration/http"
   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">

    <int:gateway id="requestGateway"
             service-interface="RequestGateway"
             default-request-channel="requestChannel">
        <int:method name="sendConfirmationEmail">
            <int:header name="Content-Type" value="application/x-www-form-urlencoded"/>
        </int:method>
    </int:gateway>

    <int:channel id="requestChannel"/>

    <int-http:outbound-gateway request-channel="requestChannel"
                           url="http://localhost"
                           http-method="POST"
                           expected-response-type="java.lang.String"/>

</beans>

Then I changed my interface to take a Map as it's argument rather than the pojo:

public interface RequestGateway {
    String echo(Map<String, String> request);
}

The pojo itself remains as before; and the class that invokes the service is changed so that it creates a Map and passes it:

public class HttpClientDemo {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("/si-email-context.xml");
        RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class);

        Pojo pojo = new Pojo("Fred", "Bloggs");

        Map<String, String> requestMap = new HashMap<String, String>();
        requestMap.put("fName", pojo.getFName());
        requestMap.put("sName", pojo.getSName());

        String reply = requestGateway.echo(requestMap);
        System.out.println("Replied with: " + reply);
    }
}

I'm sure there are several more elegant ways of transforming the pojo into a Map, but for the time being this answers my question.

To send POST parameters with a http outbound-gateway you need to set the Content-Type to application/x-www-form-urlencoded and you need to pass a Map of key/values pairs.

Share:
11,090
Nathan Russell
Author by

Nathan Russell

Updated on June 04, 2022

Comments

  • Nathan Russell
    Nathan Russell almost 2 years

    I'm trying to put together a really simple HTTP POST example using Spring Integration and a http outbound-gateway.
    I need to be able to send a HTTP POST message with some POST parameters, as I would with curl:

    $ curl -d 'fName=Fred&sName=Bloggs' http://localhost
    

    I can get it working (without the POST parameters) if I send a simple String as the argument to the interface method, but I need to send a pojo, where each property of the pojo becomes a POST parameter.

    I have the following SI config:

    <?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"
       xmlns:int-http="http://www.springframework.org/schema/integration/http"
       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">
    
        <int:gateway id="requestGateway"
                 service-interface="RequestGateway"
                 default-request-channel="requestChannel"/>
    
        <int:channel id="requestChannel"/>
    
        <int-http:outbound-gateway request-channel="requestChannel"
                               url="http://localhost"
                               http-method="POST"
                               expected-response-type="java.lang.String"/>
    
    </beans>
    

    My RequestGateway interface looks like this:

    public interface RequestGateway {
        String echo(Pojo request);
    }
    

    My Pojo class looks like this:

    public class Pojo {
        private String fName;
        private String sName;
    
        public Pojo(String fName, String sName) {
            this.fName = fName;
            this.sName = sName;
        }
    
        .... getters and setters
    }
    

    And my class to kick it all off looks like this:

    public class HttpClientDemo {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("/si-email-context.xml");
            RequestGateway requestGateway = context.getBean("requestGateway", RequestGateway.class);
    
            Pojo pojo = new Pojo("Fred", "Bloggs");
            String reply = requestGateway.echo(pojo);
            System.out.println("Replied with: " + reply);
        }
    }
    

    When I run the above, I get:

    org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [Pojo] and content type [application/x-java-serialized-object]
    

    I've googled a lot for this, but cannot find any examples of sending HTTP POST parameters with an outbound-gateway (I can find lots about setting HTTP Headers, but that's not what I'm trying to do here)
    The only thing I did find was spring-integration: how to pass post request parameters to http-outbound but it's a slightly different use case as the OP was trying to send a JSON representation of his pojo which I am not, and the answer talks about setting headers, not POST parameters.

    Any help with this would be very much appreciated;
    Thanks
    Nathan

  • Artem Bilan
    Artem Bilan over 8 years
    You can avoid Content-Type setting because HttpRequestExecutingMessageHandler takes care about that if payload is a Map only with String keys. From other side consider to use <object-to-map-transformer> instead of manual conversion.