INT-4462: WebFluxInbound: cope with empty body
JIRA: https://jira.spring.io/browse/INT-4462 When the HTTP request body is empty, the `HttpMessageReader` ends up with the empty `Mono` which can't be evaluated to any reasonable value. * Add fallback to `requestParams` when `Mono` for body is empty and also when `payloadExpression` returns null **Cherry-pick to 5.0.x**
This commit is contained in:
committed by
Gary Russell
parent
48e8b14475
commit
4d8494ae76
@@ -150,6 +150,7 @@ public class WebFluxInboundEndpoint extends BaseHttpInboundEndpoint implements W
|
||||
private Mono<Void> doHandle(ServerWebExchange exchange) {
|
||||
return extractRequestBody(exchange)
|
||||
.doOnSubscribe(s -> this.activeCount.incrementAndGet())
|
||||
.switchIfEmpty(Mono.just(exchange.getRequest().getQueryParams()))
|
||||
.map(body -> new HttpEntity<>(body, exchange.getRequest().getHeaders()))
|
||||
.map(entity -> buildMessage(entity, exchange))
|
||||
.flatMap(requestMessage -> {
|
||||
@@ -267,10 +268,6 @@ public class WebFluxInboundEndpoint extends BaseHttpInboundEndpoint implements W
|
||||
Object payload;
|
||||
if (getPayloadExpression() != null) {
|
||||
payload = getPayloadExpression().getValue(evaluationContext);
|
||||
if (payload == null) {
|
||||
throw new IllegalStateException("The payload expression '" + getPayloadExpression().getExpressionString()
|
||||
+ "' returned null.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
payload = httpEntity.getBody();
|
||||
@@ -288,6 +285,10 @@ public class WebFluxInboundEndpoint extends BaseHttpInboundEndpoint implements W
|
||||
}
|
||||
}
|
||||
|
||||
if (payload == null) {
|
||||
payload = requestParams;
|
||||
}
|
||||
|
||||
AbstractIntegrationMessageBuilder<?> messageBuilder;
|
||||
|
||||
if (payload instanceof Message<?>) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
* Copyright 2017-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -95,6 +96,16 @@ public class WebFluxInboundEndpointTests {
|
||||
.is5xxServerError();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostWithEmptyBody() {
|
||||
this.webTestClient
|
||||
.post()
|
||||
.uri("/post?foo=foo")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("{foo=[foo]}");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableWebFlux
|
||||
@EnableIntegration
|
||||
@@ -156,6 +167,22 @@ public class WebFluxInboundEndpointTests {
|
||||
return new ResponseEntity<>("<500 Internal Server Error,{}>", HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebFluxInboundEndpoint postInboundEndpoint() {
|
||||
WebFluxInboundEndpoint endpoint = new WebFluxInboundEndpoint();
|
||||
RequestMapping requestMapping = new RequestMapping();
|
||||
requestMapping.setPathPatterns("/post");
|
||||
requestMapping.setMethods(HttpMethod.POST);
|
||||
endpoint.setRequestMapping(requestMapping);
|
||||
endpoint.setRequestChannelName("postServiceChannel");
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
@ServiceActivator(inputChannel = "postServiceChannel")
|
||||
String service(Object payload) {
|
||||
return payload.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
The WebFlux Spring Integration module (`spring-integration-webflux`) allows for the execution of HTTP requests and the processing of inbound HTTP requests in Reactive manner.
|
||||
The WebFlux support consists of the following gateway implementations: `WebFluxInboundEndpoint`, `WebFluxRequestExecutingMessageHandler`.
|
||||
The implementation is fully based on the Spring http://docs.spring.io/spring/docs/5.0.0.RC3/spring-framework-reference/web.html#web-reactive[WebFlux] and https://projectreactor.io/[Project Reactor] foundations.
|
||||
The implementation is fully based on the Spring https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux[WebFlux] and https://projectreactor.io/[Project Reactor] foundations.
|
||||
Also see <<http>> for more information since many options are shared between reactive and regular HTTP components.
|
||||
|
||||
[[webflux-inbound]]
|
||||
@@ -65,6 +65,8 @@ public IntegrationFlow sseFlow() {
|
||||
|
||||
Also see <<http-request-mapping>> and <<http-cors>> for more possible configuration options.
|
||||
|
||||
When the request body is empty, or `payloadExpression` returns `null`, the request params `MultiValueMap<String, String>` is used for a `payload` of the target message to process.
|
||||
|
||||
[[webflux-outbound]]
|
||||
=== WebFlux Outbound Components
|
||||
|
||||
|
||||
Reference in New Issue
Block a user