From 54853ee239290ffedf708cc37c7bca067da98df4 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Wed, 19 Apr 2023 11:55:35 +0200 Subject: [PATCH] Support setCharacterEncoding(null) in MockHttpServletResponse Closes gh-30341 --- .../mock/web/MockHttpServletResponse.java | 38 ++++++++++++++++--- .../web/MockHttpServletResponseTests.java | 12 ++++++ .../servlet/MockHttpServletResponse.java | 38 ++++++++++++++++--- 3 files changed, 78 insertions(+), 10 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index 392efe675b2..2ecd94bfc21 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -201,15 +202,42 @@ public class MockHttpServletResponse implements HttpServletResponse { } @Override - public void setCharacterEncoding(String characterEncoding) { + public void setCharacterEncoding(@Nullable String characterEncoding) { setExplicitCharacterEncoding(characterEncoding); updateContentTypePropertyAndHeader(); } - private void setExplicitCharacterEncoding(String characterEncoding) { - Assert.notNull(characterEncoding, "'characterEncoding' must not be null"); - this.characterEncoding = characterEncoding; - this.characterEncodingSet = true; + private void setExplicitCharacterEncoding(@Nullable String characterEncoding) { + if (characterEncoding == null) { + this.characterEncoding = this.defaultCharacterEncoding; + this.characterEncodingSet = false; + if (this.contentType != null) { + try { + MediaType mediaType = MediaType.parseMediaType(this.contentType); + if (mediaType.getCharset() != null) { + Map parameters = new LinkedHashMap<>(mediaType.getParameters()); + parameters.remove("charset"); + mediaType = new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters); + this.contentType = mediaType.toString(); + } + } + catch (Exception ignored) { + String value = this.contentType; + int charsetIndex = value.toLowerCase().indexOf(CHARSET_PREFIX); + if (charsetIndex != -1) { + value = value.substring(0, charsetIndex).trim(); + if (value.endsWith(";")) { + value = value.substring(0, value.length() - 1); + } + this.contentType = value; + } + } + } + } + else { + this.characterEncoding = characterEncoding; + this.characterEncodingSet = true; + } } private void updateContentTypePropertyAndHeader() { diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java index dd61a572dae..8ba58a63e54 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java @@ -195,6 +195,18 @@ class MockHttpServletResponseTests { assertThat(response.getCharacterEncoding()).isEqualTo("UTF-8"); } + @Test + void setCharacterEncodingNull() { + response.setContentType("test/plain"); + response.setCharacterEncoding("UTF-8"); + assertThat(response.getContentType()).isEqualTo("test/plain;charset=UTF-8"); + assertThat(response.getHeader(CONTENT_TYPE)).isEqualTo("test/plain;charset=UTF-8"); + response.setCharacterEncoding(null); + assertThat(response.getContentType()).isEqualTo("test/plain"); + assertThat(response.getHeader(CONTENT_TYPE)).isEqualTo("test/plain"); + assertThat(response.getCharacterEncoding()).isEqualTo(WebUtils.DEFAULT_CHARACTER_ENCODING); + } + @Test void defaultCharacterEncoding() { assertThat(response.isCharset()).isFalse(); diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java index 0c06cb8c38d..b88907feb7d 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -201,15 +202,42 @@ public class MockHttpServletResponse implements HttpServletResponse { } @Override - public void setCharacterEncoding(String characterEncoding) { + public void setCharacterEncoding(@Nullable String characterEncoding) { setExplicitCharacterEncoding(characterEncoding); updateContentTypePropertyAndHeader(); } - private void setExplicitCharacterEncoding(String characterEncoding) { - Assert.notNull(characterEncoding, "'characterEncoding' must not be null"); - this.characterEncoding = characterEncoding; - this.characterEncodingSet = true; + private void setExplicitCharacterEncoding(@Nullable String characterEncoding) { + if (characterEncoding == null) { + this.characterEncoding = this.defaultCharacterEncoding; + this.characterEncodingSet = false; + if (this.contentType != null) { + try { + MediaType mediaType = MediaType.parseMediaType(this.contentType); + if (mediaType.getCharset() != null) { + Map parameters = new LinkedHashMap<>(mediaType.getParameters()); + parameters.remove("charset"); + mediaType = new MediaType(mediaType.getType(), mediaType.getSubtype(), parameters); + this.contentType = mediaType.toString(); + } + } + catch (Exception ignored) { + String value = this.contentType; + int charsetIndex = value.toLowerCase().indexOf(CHARSET_PREFIX); + if (charsetIndex != -1) { + value = value.substring(0, charsetIndex).trim(); + if (value.endsWith(";")) { + value = value.substring(0, value.length() - 1); + } + this.contentType = value; + } + } + } + } + else { + this.characterEncoding = characterEncoding; + this.characterEncodingSet = true; + } } private void updateContentTypePropertyAndHeader() {