Search code examples
spring-integrationspring-webfluxspring-integration-dsl

How to use Reactive Outbound Adapter HTTP POST with body


I am trying to use the Reactive Outbound Gateway in Spring Integration, but the documentation is not clear at all on how to add a POST body, including the sample tests.

Please help.

When using the WebClient builder you cannot add a POST body (I tried create()), but it doesn't return the WebClient type that's needed.

WebClient c = WebClient.builder()
                .baseUrl("http://myurl.com")
                .build();

//can add a body after doing this, but you this cannot get passed into the method, because it executes the call

c.post()
 .headers(h -> h.setContentType(MediaType.APPLICATION_JSON))
 .body(BodyInserters.fromValue(m.getPayload()))
 .retrieve()
 .bodyToMono(String.class)


This is the example from the Spring docs -- not sure what they are POSTING

https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/webflux.html

@ServiceActivator(inputChannel = "reactiveHttpOutRequest")
@Bean
public WebFluxRequestExecutingMessageHandler reactiveOutbound(WebClient client) {
    WebFluxRequestExecutingMessageHandler handler =
        new WebFluxRequestExecutingMessageHandler("http://localhost:8080/foo", client);
    handler.setHttpMethod(HttpMethod.POST);
    handler.setExpectedResponseType(String.class);
    return handler;

Solution

  • not sure what they are POSTING

    Long story short: the payload of the request message on that reactiveHttpOutRequest.

    Please, make yourself familiar with Enterprise Integration Patterns to be sure that you understand what is message and how it is handled on the service activator. And of course how to give the data for that service activator via sending the message into a channel.

    There is no difference what kind of outbound channel adapter you use: it always deals with the message sent to its input channel and its payload.

    To be more precise here is a source code of that WebFluxRequestExecutingMessageHandler where we set a body into a WebClient request:

        BodyInserter<?, ? super ClientHttpRequest> inserter = buildBodyInserterForRequest(requestMessage, httpRequest);
        if (inserter != null) {
            requestSpec.body(inserter);
        }
    

    This one is used from here:

    protected Object exchange(Object uri, HttpMethod httpMethod, HttpEntity<?> httpRequest,
            Object expectedResponseType, Message<?> requestMessage, Map<String, ?> uriVariables) {
    
        WebClient.RequestBodySpec requestSpec =
                createRequestBodySpec(uri, httpMethod, httpRequest, requestMessage, uriVariables);
    

    That exchange() is called from here:

    protected Object handleRequestMessage(Message<?> requestMessage) {
    

    This handleRequestMessage() is called from the MessageHandler.handleMessage(), which, in turn, is called when a MessageChannel delivers the message sent into it.