11/*
2- * Copyright 2017-2024 the original author or authors.
2+ * Copyright 2017-2025 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1919import java .net .URI ;
2020import java .util .Map ;
2121
22+ import org .jspecify .annotations .Nullable ;
2223import org .reactivestreams .Publisher ;
2324import reactor .core .publisher .Flux ;
2425import reactor .core .publisher .Mono ;
3940import org .springframework .integration .expression .ExpressionUtils ;
4041import org .springframework .integration .expression .ValueExpression ;
4142import org .springframework .integration .http .outbound .AbstractHttpRequestExecutingMessageHandler ;
42- import org .springframework .lang .Nullable ;
4343import org .springframework .messaging .Message ;
4444import org .springframework .util .Assert ;
4545import org .springframework .util .CollectionUtils ;
@@ -78,12 +78,13 @@ public class WebFluxRequestExecutingMessageHandler extends AbstractHttpRequestEx
7878
7979 private boolean replyPayloadToFlux ;
8080
81- private BodyExtractor <?, ? super ClientHttpResponse > bodyExtractor ;
81+ private @ Nullable BodyExtractor <?, ? super ClientHttpResponse > bodyExtractor ;
8282
83- private Expression publisherElementTypeExpression ;
83+ private @ Nullable Expression publisherElementTypeExpression ;
8484
85- private Expression attributeVariablesExpression ;
85+ private @ Nullable Expression attributeVariablesExpression ;
8686
87+ @ SuppressWarnings ("NullAway.Init" )
8788 private StandardEvaluationContext evaluationContext ;
8889
8990 /**
@@ -131,14 +132,18 @@ public WebFluxRequestExecutingMessageHandler(String uri, @Nullable WebClient web
131132 * {@link org.springframework.beans.factory.BeanFactory}.
132133 * @param webClient The WebClient to use.
133134 */
135+ @ SuppressWarnings ("this-escape" )
134136 public WebFluxRequestExecutingMessageHandler (Expression uriExpression , @ Nullable WebClient webClient ) {
135137 super (uriExpression );
136- this .webClientExplicitlySet = webClient != null ;
137- this .webClient =
138- !this .webClientExplicitlySet
139- ? WebClient .builder ().uriBuilderFactory (this .uriFactory ).build ()
140- : webClient ;
141- this .setAsync (true );
138+ if (webClient != null ) {
139+ this .webClientExplicitlySet = true ;
140+ this .webClient = webClient ;
141+ }
142+ else {
143+ this .webClientExplicitlySet = false ;
144+ this .webClient = WebClient .builder ().uriBuilderFactory (this .uriFactory ).build ();
145+ }
146+ setAsync (true );
142147 }
143148
144149 private void assertLocalWebClient (String option ) {
@@ -244,6 +249,7 @@ protected Object exchange(Object uri, HttpMethod httpMethod, HttpEntity<?> httpR
244249 }
245250 }
246251
252+ @ SuppressWarnings (UNCHECKED )
247253 private WebClient .RequestBodySpec createRequestBodySpec (Object uri , HttpMethod httpMethod ,
248254 HttpEntity <?> httpRequest , Message <?> requestMessage , Map <String , ?> uriVariables ) {
249255
@@ -259,8 +265,10 @@ private WebClient.RequestBodySpec createRequestBodySpec(Object uri, HttpMethod h
259265
260266 requestSpec = requestSpec .headers (headers -> headers .putAll (httpRequest .getHeaders ()));
261267
262- if (this .attributeVariablesExpression != null ) {
263- Map <String , Object > attributeMap = evaluateAttributeVariables (requestMessage );
268+ Expression attributeVariablesExpressionToUse = this .attributeVariablesExpression ;
269+ if (attributeVariablesExpressionToUse != null ) {
270+ Map <String , Object > attributeMap =
271+ attributeVariablesExpressionToUse .getValue (this .evaluationContext , requestMessage , Map .class );
264272 if (!CollectionUtils .isEmpty (attributeMap )) {
265273 requestSpec = requestSpec .attributes (map -> map .putAll (attributeMap ));
266274 }
@@ -273,11 +281,6 @@ private WebClient.RequestBodySpec createRequestBodySpec(Object uri, HttpMethod h
273281 return requestSpec ;
274282 }
275283
276- @ SuppressWarnings (UNCHECKED )
277- private Map <String , Object > evaluateAttributeVariables (Message <?> requestMessage ) {
278- return this .attributeVariablesExpression .getValue (this .evaluationContext , requestMessage , Map .class );
279- }
280-
281284 @ Nullable
282285 private BodyInserter <?, ? super ClientHttpRequest > buildBodyInserterForRequest (Message <?> requestMessage ,
283286 HttpEntity <?> httpRequest ) {
@@ -323,10 +326,9 @@ else if (publisherElementType instanceof ParameterizedTypeReference<?>) {
323326 return inserter ;
324327 }
325328
326- @ Nullable
327329 @ SuppressWarnings (UNCHECKED )
328- private static BodyInserters .FormInserter <?> buildBodyInserterForMultiValueMap (
329- MultiValueMap <?, ?> requestBody , MediaType contentType ) {
330+ private static BodyInserters .@ Nullable FormInserter <?> buildBodyInserterForMultiValueMap (
331+ MultiValueMap <?, ?> requestBody , @ Nullable MediaType contentType ) {
330332
331333 if (MediaType .APPLICATION_FORM_URLENCODED .equals (contentType )) {
332334 return BodyInserters .fromFormData ((MultiValueMap <String , String >) requestBody );
@@ -349,7 +351,8 @@ private Mono<ResponseEntity<Flux<Object>>> exchangeForResponseMono(WebClient.Req
349351
350352 @ SuppressWarnings ({UNCHECKED , "rawtypes" })
351353 private BodyExtractor <Flux <Object >, ? super ClientHttpResponse > createBodyExtractor (Object expectedResponseType ) {
352- if (expectedResponseType != null ) {
354+ BodyExtractor <?, ? super ClientHttpResponse > bodyExtractorToUse = this .bodyExtractor ;
355+ if (expectedResponseType != Void .class ) {
353356 if (this .replyPayloadToFlux ) {
354357 if (expectedResponseType instanceof ParameterizedTypeReference parameterizedTypeReference ) {
355358 return BodyExtractors .toFlux (parameterizedTypeReference );
@@ -369,9 +372,9 @@ private Mono<ResponseEntity<Flux<Object>>> exchangeForResponseMono(WebClient.Req
369372 return (inputMessage , context ) -> Flux .from (monoExtractor .extract (inputMessage , context ));
370373 }
371374 }
372- else if (this . bodyExtractor != null ) {
375+ else if (bodyExtractorToUse != null ) {
373376 return (inputMessage , context ) -> {
374- Object body = this . bodyExtractor .extract (inputMessage , context );
377+ Object body = bodyExtractorToUse .extract (inputMessage , context );
375378 if (body instanceof Publisher publisher ) {
376379 return Flux .from (publisher );
377380 }
0 commit comments