Spring Integration - how to send POST parameters w

2019-05-24 03:39发布

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

1条回答
姐就是有狂的资本
2楼-- · 2019-05-24 04:08

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.

查看更多
登录 后发表回答