From 75fd391fc716456bbd2448f60e691b8f588c70de Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 2 Jan 2020 11:29:04 +0100 Subject: [PATCH] Remove quality parameter from selected media type Prior to this commit, WebFlux application would keep the quality parameter from the "Accept" request header when selecting a media type for the response. It would then echo it back to the client. While strictly not wrong, this is unnecessary and can confuse HTTP clients. This commit aligns WebFlux's behavior with Spring MVC. Fixes gh-24239 --- .../result/HandlerResultHandlerSupport.java | 1 + .../result/HandlerResultHandlerTests.java | 23 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java index e974f42703e..bf2fbe214bc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java @@ -156,6 +156,7 @@ public abstract class HandlerResultHandlerSupport implements Ordered { } if (selected != null) { + selected = selected.removeQualityValue(); if (logger.isDebugEnabled()) { logger.debug("Using '" + selected + "' given " + acceptableTypes + " and supported " + producibleTypes); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java index 98121a60719..28c3522088f 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/HandlerResultHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class HandlerResultHandlerTests { @Test - public void usesContentTypeResolver() throws Exception { + void usesContentTypeResolver() { TestResultHandler resultHandler = new TestResultHandler(new FixedContentTypeResolver(IMAGE_GIF)); List mediaTypes = Arrays.asList(IMAGE_JPEG, IMAGE_GIF, IMAGE_PNG); MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path")); @@ -61,7 +61,7 @@ public class HandlerResultHandlerTests { } @Test - public void producibleMediaTypesRequestAttribute() throws Exception { + void producibleMediaTypesRequestAttribute() { MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path")); exchange.getAttributes().put(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(IMAGE_GIF)); @@ -72,7 +72,7 @@ public class HandlerResultHandlerTests { } @Test // SPR-9160 - public void sortsByQuality() throws Exception { + void sortsByQuality() { MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path") .header("Accept", "text/plain; q=0.5, application/json")); @@ -83,7 +83,7 @@ public class HandlerResultHandlerTests { } @Test - public void charsetFromAcceptHeader() throws Exception { + void charsetFromAcceptHeader() { MediaType text8859 = MediaType.parseMediaType("text/plain;charset=ISO-8859-1"); MediaType textUtf8 = MediaType.parseMediaType("text/plain;charset=UTF-8"); MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path").accept(text8859)); @@ -93,7 +93,7 @@ public class HandlerResultHandlerTests { } @Test // SPR-12894 - public void noConcreteMediaType() throws Exception { + void noConcreteMediaType() { List producible = Collections.singletonList(ALL); MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path")); MediaType actual = this.resultHandler.selectMediaType(exchange, () -> producible); @@ -101,6 +101,17 @@ public class HandlerResultHandlerTests { assertThat(actual).isEqualTo(APPLICATION_OCTET_STREAM); } + @Test + void removeQualityParameter() { + MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/path") + .header("Accept", "text/plain; q=0.5")); + + List mediaTypes = Arrays.asList(APPLICATION_JSON, TEXT_PLAIN); + MediaType actual = this.resultHandler.selectMediaType(exchange, () -> mediaTypes); + + assertThat(actual).isEqualTo(TEXT_PLAIN); + } + @SuppressWarnings("WeakerAccess") private static class TestResultHandler extends HandlerResultHandlerSupport {