Skip to content

Commit 5de549d

Browse files
committed
Update contentType property via MockHttpServletResponse::setCharacterEncoding()
Prior to this commit, MockHttpServletResponse's setCharacterEncoding() method did not update the contentType property, which violates the Servlet 2.4 Javadoc for getContentType() and setCharacterEncoding(). This commit addresses this issue; however, some existing tests may have to be updated as a result of this change. For example, note how some of the tests in this commit have been refactored to use MediaType##isCompatibleWith() instead of asserting exact matches for the value returned by MockHttpServletResponse's getContentType() method. Closes gh-25536
1 parent c5bb5d6 commit 5de549d

File tree

6 files changed

+44
-60
lines changed

6 files changed

+44
-60
lines changed

spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,15 @@ public boolean isCharset() {
169169
public void setCharacterEncoding(String characterEncoding) {
170170
this.characterEncoding = characterEncoding;
171171
this.charset = true;
172-
updateContentTypeHeader();
172+
updateContentTypePropertyAndHeader();
173173
}
174174

175-
private void updateContentTypeHeader() {
175+
private void updateContentTypePropertyAndHeader() {
176176
if (this.contentType != null) {
177177
String value = this.contentType;
178178
if (this.charset && !this.contentType.toLowerCase().contains(CHARSET_PREFIX)) {
179179
value = value + ';' + CHARSET_PREFIX + this.characterEncoding;
180+
this.contentType = value;
180181
}
181182
doAddHeaderValue(HttpHeaders.CONTENT_TYPE, value, true);
182183
}
@@ -280,7 +281,7 @@ public void setContentType(@Nullable String contentType) {
280281
this.charset = true;
281282
}
282283
}
283-
updateContentTypeHeader();
284+
updateContentTypePropertyAndHeader();
284285
}
285286
}
286287

spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void contentLanguageHeaderWithMultipleValues() {
144144
void setContentTypeThenCharacterEncoding() {
145145
response.setContentType("test/plain");
146146
response.setCharacterEncoding("UTF-8");
147-
assertThat(response.getContentType()).isEqualTo("test/plain");
147+
assertThat(response.getContentType()).isEqualTo("test/plain;charset=UTF-8");
148148
assertThat(response.getHeader(CONTENT_TYPE)).isEqualTo("test/plain;charset=UTF-8");
149149
assertThat(response.getCharacterEncoding()).isEqualTo("UTF-8");
150150
}
@@ -153,7 +153,7 @@ void setContentTypeThenCharacterEncoding() {
153153
void setCharacterEncodingThenContentType() {
154154
response.setCharacterEncoding("UTF-8");
155155
response.setContentType("test/plain");
156-
assertThat(response.getContentType()).isEqualTo("test/plain");
156+
assertThat(response.getContentType()).isEqualTo("test/plain;charset=UTF-8");
157157
assertThat(response.getHeader(CONTENT_TYPE)).isEqualTo("test/plain;charset=UTF-8");
158158
assertThat(response.getCharacterEncoding()).isEqualTo("UTF-8");
159159
}
@@ -488,7 +488,7 @@ void resetResetsCharset() {
488488
assertThat(response.isCharset()).isTrue();
489489
assertThat(response.getCharacterEncoding()).isEqualTo("UTF-8");
490490
response.setContentType("text/plain");
491-
assertThat(response.getContentType()).isEqualTo("text/plain");
491+
assertThat(response.getContentType()).isEqualTo("text/plain;charset=UTF-8");
492492
String contentTypeHeader = response.getHeader(CONTENT_TYPE);
493493
assertThat(contentTypeHeader).isEqualTo("text/plain;charset=UTF-8");
494494

spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/ViewResolutionTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void jsonOnly() throws Exception {
7373
standaloneSetup(new PersonController()).setSingleView(new MappingJackson2JsonView()).build()
7474
.perform(get("/person/Corea"))
7575
.andExpect(status().isOk())
76-
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
76+
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
7777
.andExpect(jsonPath("$.person.name").value("Corea"));
7878
}
7979

@@ -119,7 +119,7 @@ void contentNegotiation() throws Exception {
119119

120120
mockMvc.perform(get("/person/Corea").accept(MediaType.APPLICATION_JSON))
121121
.andExpect(status().isOk())
122-
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
122+
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
123123
.andExpect(jsonPath("$.person.name").value("Corea"));
124124

125125
mockMvc.perform(get("/person/Corea").accept(MediaType.APPLICATION_XML))
@@ -150,4 +150,3 @@ String show(@PathVariable String name, Model model) {
150150
}
151151

152152
}
153-

spring-web/src/testFixtures/java/org/springframework/web/testfixture/servlet/MockHttpServletResponse.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,15 @@ public boolean isCharset() {
169169
public void setCharacterEncoding(String characterEncoding) {
170170
this.characterEncoding = characterEncoding;
171171
this.charset = true;
172-
updateContentTypeHeader();
172+
updateContentTypePropertyAndHeader();
173173
}
174174

175-
private void updateContentTypeHeader() {
175+
private void updateContentTypePropertyAndHeader() {
176176
if (this.contentType != null) {
177177
String value = this.contentType;
178178
if (this.charset && !this.contentType.toLowerCase().contains(CHARSET_PREFIX)) {
179179
value = value + ';' + CHARSET_PREFIX + this.characterEncoding;
180+
this.contentType = value;
180181
}
181182
doAddHeaderValue(HttpHeaders.CONTENT_TYPE, value, true);
182183
}
@@ -280,7 +281,7 @@ public void setContentType(@Nullable String contentType) {
280281
this.charset = true;
281282
}
282283
}
283-
updateContentTypeHeader();
284+
updateContentTypePropertyAndHeader();
284285
}
285286
}
286287

spring-webmvc/src/test/java/org/springframework/web/servlet/view/json/MappingJackson2JsonViewTests.java

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,7 +38,6 @@
3838
import com.fasterxml.jackson.databind.ser.SerializerFactory;
3939
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
4040
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
41-
import org.junit.jupiter.api.BeforeEach;
4241
import org.junit.jupiter.api.Test;
4342
import org.mozilla.javascript.Context;
4443
import org.mozilla.javascript.ContextFactory;
@@ -60,30 +59,19 @@
6059
* @author Arjen Poutsma
6160
* @author Rossen Stoyanchev
6261
* @author Sebastien Deleuze
62+
* @author Sam Brannen
6363
*/
6464
public class MappingJackson2JsonViewTests {
6565

66-
private MappingJackson2JsonView view;
66+
private MappingJackson2JsonView view = new MappingJackson2JsonView();
6767

68-
private MockHttpServletRequest request;
68+
private MockHttpServletRequest request = new MockHttpServletRequest();
6969

70-
private MockHttpServletResponse response;
70+
private MockHttpServletResponse response = new MockHttpServletResponse();
7171

72-
private Context jsContext;
72+
private Context jsContext = ContextFactory.getGlobal().enterContext();
7373

74-
private ScriptableObject jsScope;
75-
76-
77-
@BeforeEach
78-
public void setUp() {
79-
request = new MockHttpServletRequest();
80-
response = new MockHttpServletResponse();
81-
82-
jsContext = ContextFactory.getGlobal().enterContext();
83-
jsScope = jsContext.initStandardObjects();
84-
85-
view = new MappingJackson2JsonView();
86-
}
74+
private ScriptableObject jsScope = jsContext.initStandardObjects();
8775

8876

8977
@Test
@@ -102,7 +90,8 @@ public void renderSimpleMap() throws Exception {
10290

10391
assertThat(response.getHeader("Cache-Control")).isEqualTo("no-store");
10492

105-
assertThat(response.getContentType()).isEqualTo(MappingJackson2JsonView.DEFAULT_CONTENT_TYPE);
93+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
94+
assertThat(mediaType.isCompatibleWith(MediaType.parseMediaType(MappingJackson2JsonView.DEFAULT_CONTENT_TYPE))).isTrue();
10695

10796
String jsonResult = response.getContentAsString();
10897
assertThat(jsonResult.length() > 0).isTrue();
@@ -117,12 +106,14 @@ public void renderWithSelectedContentType() throws Exception {
117106
model.put("foo", "bar");
118107

119108
view.render(model, request, response);
120-
assertThat(response.getContentType()).isEqualTo("application/json");
109+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
110+
assertThat(mediaType.isCompatibleWith(MediaType.APPLICATION_JSON)).isTrue();
121111

122112
request.setAttribute(View.SELECTED_CONTENT_TYPE, new MediaType("application", "vnd.example-v2+xml"));
123113
view.render(model, request, response);
124114

125-
assertThat(response.getContentType()).isEqualTo("application/vnd.example-v2+xml");
115+
mediaType = MediaType.parseMediaType(response.getContentType());
116+
assertThat(mediaType.isCompatibleWith(MediaType.parseMediaType("application/vnd.example-v2+xml"))).isTrue();
126117
}
127118

128119
@Test
@@ -326,10 +317,10 @@ private void validateResult() throws Exception {
326317
if (jsonPrefix != null) {
327318
json = json.substring(5);
328319
}
329-
Object jsResult =
330-
jsContext.evaluateString(jsScope, "(" + json + ")", "JSON Stream", 1, null);
320+
Object jsResult = jsContext.evaluateString(jsScope, "(" + json + ")", "JSON Stream", 1, null);
331321
assertThat(jsResult).as("Json Result did not eval as valid JavaScript").isNotNull();
332-
assertThat(response.getContentType()).isEqualTo("application/json");
322+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
323+
assertThat(mediaType.isCompatibleWith(MediaType.APPLICATION_JSON)).isTrue();
333324
}
334325

335326

spring-webmvc/src/test/java/org/springframework/web/servlet/view/xml/MappingJackson2XmlViewTests.java

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,6 @@
3333
import com.fasterxml.jackson.databind.ser.BeanSerializerFactory;
3434
import com.fasterxml.jackson.databind.ser.SerializerFactory;
3535
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
36-
import org.junit.jupiter.api.BeforeEach;
3736
import org.junit.jupiter.api.Test;
3837
import org.mozilla.javascript.Context;
3938
import org.mozilla.javascript.ContextFactory;
@@ -51,30 +50,19 @@
5150

5251
/**
5352
* @author Sebastien Deleuze
53+
* @author Sam Brannen
5454
*/
5555
public class MappingJackson2XmlViewTests {
5656

57-
private MappingJackson2XmlView view;
57+
private MappingJackson2XmlView view = new MappingJackson2XmlView();
5858

59-
private MockHttpServletRequest request;
59+
private MockHttpServletRequest request = new MockHttpServletRequest();
6060

61-
private MockHttpServletResponse response;
61+
private MockHttpServletResponse response = new MockHttpServletResponse();
6262

63-
private Context jsContext;
63+
private Context jsContext = ContextFactory.getGlobal().enterContext();
6464

65-
private ScriptableObject jsScope;
66-
67-
68-
@BeforeEach
69-
public void setUp() {
70-
request = new MockHttpServletRequest();
71-
response = new MockHttpServletResponse();
72-
73-
jsContext = ContextFactory.getGlobal().enterContext();
74-
jsScope = jsContext.initStandardObjects();
75-
76-
view = new MappingJackson2XmlView();
77-
}
65+
private ScriptableObject jsScope = jsContext.initStandardObjects();
7866

7967

8068
@Test
@@ -93,7 +81,8 @@ public void renderSimpleMap() throws Exception {
9381

9482
assertThat(response.getHeader("Cache-Control")).isEqualTo("no-store");
9583

96-
assertThat(response.getContentType()).isEqualTo(MappingJackson2XmlView.DEFAULT_CONTENT_TYPE);
84+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
85+
assertThat(mediaType.isCompatibleWith(MediaType.parseMediaType(MappingJackson2XmlView.DEFAULT_CONTENT_TYPE))).isTrue();
9786

9887
String jsonResult = response.getContentAsString();
9988
assertThat(jsonResult.length() > 0).isTrue();
@@ -108,12 +97,14 @@ public void renderWithSelectedContentType() throws Exception {
10897
model.put("foo", "bar");
10998

11099
view.render(model, request, response);
111-
assertThat(response.getContentType()).isEqualTo("application/xml");
100+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
101+
assertThat(mediaType.isCompatibleWith(MediaType.APPLICATION_XML)).isTrue();
112102

113103
request.setAttribute(View.SELECTED_CONTENT_TYPE, new MediaType("application", "vnd.example-v2+xml"));
114104
view.render(model, request, response);
115105

116-
assertThat(response.getContentType()).isEqualTo("application/vnd.example-v2+xml");
106+
mediaType = MediaType.parseMediaType(response.getContentType());
107+
assertThat(mediaType.isCompatibleWith(MediaType.parseMediaType("application/vnd.example-v2+xml"))).isTrue();
117108
}
118109

119110
@Test
@@ -232,7 +223,8 @@ private void validateResult() throws Exception {
232223
Object xmlResult =
233224
jsContext.evaluateString(jsScope, "(" + response.getContentAsString() + ")", "XML Stream", 1, null);
234225
assertThat(xmlResult).as("XML Result did not eval as valid JavaScript").isNotNull();
235-
assertThat(response.getContentType()).isEqualTo("application/xml");
226+
MediaType mediaType = MediaType.parseMediaType(response.getContentType());
227+
assertThat(mediaType.isCompatibleWith(MediaType.APPLICATION_XML)).isTrue();
236228
}
237229

238230

0 commit comments

Comments
 (0)