Skip to content

Commit 40df0b9

Browse files
committed
Fix nullability in the webflux.outbound package
1 parent 6d2380d commit 40df0b9

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

spring-integration-webflux/src/main/java/org/springframework/integration/webflux/outbound/WebFluxRequestExecutingMessageHandler.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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.
@@ -19,6 +19,7 @@
1919
import java.net.URI;
2020
import java.util.Map;
2121

22+
import org.jspecify.annotations.Nullable;
2223
import org.reactivestreams.Publisher;
2324
import reactor.core.publisher.Flux;
2425
import reactor.core.publisher.Mono;
@@ -39,7 +40,6 @@
3940
import org.springframework.integration.expression.ExpressionUtils;
4041
import org.springframework.integration.expression.ValueExpression;
4142
import org.springframework.integration.http.outbound.AbstractHttpRequestExecutingMessageHandler;
42-
import org.springframework.lang.Nullable;
4343
import org.springframework.messaging.Message;
4444
import org.springframework.util.Assert;
4545
import 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
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/**
22
* Provides classes supporting outbound endpoints.
33
*/
4+
@org.jspecify.annotations.NullMarked
45
package org.springframework.integration.webflux.outbound;

0 commit comments

Comments
 (0)