Skip to content

Commit 4b18cc9

Browse files
committed
Merge branch '5.3.x'
2 parents 3eaf259 + f919439 commit 4b18cc9

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseBuilder.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.springframework.util.Assert;
4141
import org.springframework.util.LinkedMultiValueMap;
4242
import org.springframework.util.MultiValueMap;
43+
import org.springframework.web.reactive.result.view.RedirectView;
44+
import org.springframework.web.reactive.result.view.View;
4345
import org.springframework.web.reactive.result.view.ViewResolver;
4446
import org.springframework.web.server.ServerWebExchange;
4547

@@ -194,13 +196,24 @@ protected Mono<Void> writeToInternal(ServerWebExchange exchange, Context context
194196
.switchIfEmpty(Mono.error(() ->
195197
new IllegalArgumentException("Could not resolve view with name '" + name() + "'")))
196198
.flatMap(view -> {
199+
setStatus(view);
197200
List<MediaType> mediaTypes = view.getSupportedMediaTypes();
198201
return view.render(model(),
199202
contentType == null && !mediaTypes.isEmpty() ? mediaTypes.get(0) : contentType,
200203
exchange);
201204
});
202205
}
203206

207+
private void setStatus(View view) {
208+
if (view instanceof RedirectView) {
209+
HttpStatus httpStatus = HttpStatus.resolve(rawStatusCode());
210+
if (httpStatus != null && httpStatus.is3xxRedirection()) {
211+
RedirectView redirectView = (RedirectView) view;
212+
redirectView.setStatusCode(httpStatus);
213+
}
214+
}
215+
}
216+
204217
}
205218

206219
}

spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseTests.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.web.reactive.function.server;
1818

19+
import java.time.Duration;
1920
import java.time.ZonedDateTime;
2021
import java.time.format.DateTimeFormatter;
2122
import java.time.temporal.ChronoUnit;
@@ -37,6 +38,7 @@
3738
import org.springframework.util.LinkedMultiValueMap;
3839
import org.springframework.util.MultiValueMap;
3940
import org.springframework.web.reactive.result.view.AbstractView;
41+
import org.springframework.web.reactive.result.view.RedirectView;
4042
import org.springframework.web.reactive.result.view.View;
4143
import org.springframework.web.reactive.result.view.ViewResolver;
4244
import org.springframework.web.reactive.result.view.ViewResolverSupport;
@@ -47,8 +49,10 @@
4749

4850
import static org.assertj.core.api.Assertions.assertThat;
4951
import static org.mockito.ArgumentMatchers.any;
52+
import static org.mockito.ArgumentMatchers.eq;
5053
import static org.mockito.BDDMockito.given;
5154
import static org.mockito.Mockito.mock;
55+
import static org.mockito.Mockito.verify;
5256

5357
/**
5458
* @author Arjen Poutsma
@@ -155,6 +159,41 @@ public void render() {
155159
.verify();
156160
}
157161

162+
@Test
163+
public void writeTo() {
164+
Map<String, Object> model = Collections.singletonMap("foo", "bar");
165+
RenderingResponse renderingResponse = RenderingResponse.create("view")
166+
.status(HttpStatus.FOUND)
167+
.modelAttributes(model)
168+
.build().block(Duration.of(5, ChronoUnit.MILLIS));
169+
assertThat(renderingResponse).isNotNull();
170+
171+
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("http://localhost"));
172+
MediaType contentType = MediaType.APPLICATION_PDF;
173+
exchange.getResponse().getHeaders().setContentType(contentType);
174+
175+
ViewResolver viewResolver = mock(ViewResolver.class);
176+
RedirectView view = mock(RedirectView.class);
177+
given(viewResolver.resolveViewName(eq("view"), any())).willReturn(Mono.just(view));
178+
given(view.render(model, contentType, exchange)).willReturn(Mono.empty());
179+
180+
List<ViewResolver> viewResolvers = new ArrayList<>();
181+
viewResolvers.add(viewResolver);
182+
183+
HandlerStrategies mockConfig = mock(HandlerStrategies.class);
184+
given(mockConfig.viewResolvers()).willReturn(viewResolvers);
185+
186+
ServerResponse.Context context = mock(ServerResponse.Context.class);
187+
given(context.viewResolvers()).willReturn(viewResolvers);
188+
189+
Mono<Void> result = renderingResponse.writeTo(exchange, context);
190+
StepVerifier.create(result)
191+
.expectComplete()
192+
.verify();
193+
194+
verify(view).setStatusCode(HttpStatus.FOUND);
195+
}
196+
158197
@Test
159198
public void defaultContentType() {
160199
Mono<RenderingResponse> result = RenderingResponse.create("view").build();

0 commit comments

Comments
 (0)