Browse Source

Set default view content-type with WebFlux fn

With this commit, the default content-type defined by the
view (usually "text/html;charset=UTF-8" defined in AbstractView)
is used if any, when none is defined in the response headers.

Issue: SPR-16247
pull/1626/head
sdeleuze 7 years ago
parent
commit
99cbfd32c3
  1. 9
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseBuilder.java
  2. 38
      spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DefaultRenderingResponseTests.java

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

@ -20,6 +20,7 @@ import java.util.Arrays; @@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
@ -177,7 +178,7 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -177,7 +178,7 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
public Mono<Void> writeTo(ServerWebExchange exchange, Context context) {
ServerHttpResponse response = exchange.getResponse();
writeStatusAndHeaders(response);
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
MediaType responseContentType = exchange.getResponse().getHeaders().getContentType();
Locale locale = LocaleContextHolder.getLocale(exchange.getLocaleContext());
Stream<ViewResolver> viewResolverStream = context.viewResolvers().stream();
@ -186,7 +187,11 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder { @@ -186,7 +187,11 @@ class DefaultRenderingResponseBuilder implements RenderingResponse.Builder {
.next()
.switchIfEmpty(Mono.error(new IllegalArgumentException("Could not resolve view with name '" +
name() +"'")))
.flatMap(view -> view.render(model(), contentType, exchange));
.flatMap(view -> {
List<MediaType> mediaTypes = view.getSupportedMediaTypes();
MediaType contentType = (responseContentType == null && !mediaTypes.isEmpty() ? mediaTypes.get(0) : responseContentType);
return view.render(model(), contentType, exchange);
});
}
}

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

@ -28,14 +28,19 @@ import reactor.core.publisher.Mono; @@ -28,14 +28,19 @@ import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.web.test.server.MockServerWebExchange;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.result.view.AbstractView;
import org.springframework.web.reactive.result.view.View;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.reactive.result.view.ViewResolverSupport;
import org.springframework.web.server.ServerWebExchange;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
/**
@ -143,4 +148,37 @@ public class DefaultRenderingResponseTests { @@ -143,4 +148,37 @@ public class DefaultRenderingResponseTests {
.verify();
}
@Test
public void defaultContentType() throws Exception {
Mono<RenderingResponse> result = RenderingResponse.create("view").build();
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("http://localhost"));
TestView view = new TestView();
ViewResolver viewResolver = mock(ViewResolver.class);
when(viewResolver.resolveViewName(any(), any())).thenReturn(Mono.just(view));
List<ViewResolver> viewResolvers = new ArrayList<>();
viewResolvers.add(viewResolver);
ServerResponse.Context context = mock(ServerResponse.Context.class);
when(context.viewResolvers()).thenReturn(viewResolvers);
StepVerifier.create(result.flatMap(response -> response.writeTo(exchange, context)))
.verifyComplete();
assertEquals(ViewResolverSupport.DEFAULT_CONTENT_TYPE, exchange.getResponse().getHeaders().getContentType());
}
private static class TestView extends AbstractView {
@Override
protected Mono<Void> renderInternal(Map<String, Object> renderAttributes,
MediaType contentType, ServerWebExchange exchange) {
return Mono.empty();
}
}
}

Loading…
Cancel
Save