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
This commit is contained in:
		
							parent
							
								
									e3e4f37222
								
							
						
					
					
						commit
						99cbfd32c3
					
				| 
						 | 
				
			
			@ -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 {
 | 
			
		|||
		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 {
 | 
			
		|||
					.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);
 | 
			
		||||
					});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		|||
				.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…
	
		Reference in New Issue