Ensure characterEncoding in MockHttpServletResponse is non-null
Closes gh-27219
This commit is contained in:
parent
915f1027a5
commit
96ee8a3bc7
|
@ -80,7 +80,6 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
|
||||
private boolean writerAccessAllowed = true;
|
||||
|
||||
@Nullable
|
||||
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||
|
||||
/**
|
||||
|
@ -171,8 +170,8 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* Determine whether the character encoding has been explicitly set through
|
||||
* {@link HttpServletResponse} methods or through a {@code charset} parameter
|
||||
* on the {@code Content-Type}.
|
||||
* <p>If {@code false}, {@link #getCharacterEncoding()} will return a default
|
||||
* encoding value.
|
||||
* <p>If {@code false}, {@link #getCharacterEncoding()} will return the default
|
||||
* character encoding.
|
||||
*/
|
||||
public boolean isCharset() {
|
||||
return this.characterEncodingSet;
|
||||
|
@ -180,16 +179,21 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
|
||||
@Override
|
||||
public void setCharacterEncoding(String characterEncoding) {
|
||||
setExplicitCharacterEncoding(characterEncoding);
|
||||
updateContentTypePropertyAndHeader();
|
||||
}
|
||||
|
||||
private void setExplicitCharacterEncoding(String characterEncoding) {
|
||||
Assert.notNull(characterEncoding, "'characterEncoding' must not be null");
|
||||
this.characterEncoding = characterEncoding;
|
||||
this.characterEncodingSet = true;
|
||||
updateContentTypePropertyAndHeader();
|
||||
}
|
||||
|
||||
private void updateContentTypePropertyAndHeader() {
|
||||
if (this.contentType != null) {
|
||||
String value = this.contentType;
|
||||
if (this.characterEncodingSet && !this.contentType.toLowerCase().contains(CHARSET_PREFIX)) {
|
||||
value = value + ';' + CHARSET_PREFIX + this.characterEncoding;
|
||||
if (this.characterEncodingSet && !value.toLowerCase().contains(CHARSET_PREFIX)) {
|
||||
value += ';' + CHARSET_PREFIX + getCharacterEncoding();
|
||||
this.contentType = value;
|
||||
}
|
||||
doAddHeaderValue(HttpHeaders.CONTENT_TYPE, value, true);
|
||||
|
@ -197,7 +201,6 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getCharacterEncoding() {
|
||||
return this.characterEncoding;
|
||||
}
|
||||
|
@ -212,9 +215,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
||||
Assert.state(this.writerAccessAllowed, "Writer access not allowed");
|
||||
if (this.writer == null) {
|
||||
Writer targetWriter = (this.characterEncoding != null ?
|
||||
new OutputStreamWriter(this.content, this.characterEncoding) :
|
||||
new OutputStreamWriter(this.content));
|
||||
Writer targetWriter = new OutputStreamWriter(this.content, getCharacterEncoding());
|
||||
this.writer = new ResponsePrintWriter(targetWriter);
|
||||
}
|
||||
return this.writer;
|
||||
|
@ -228,14 +229,16 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* Get the content of the response body as a {@code String}, using the charset
|
||||
* specified for the response by the application, either through
|
||||
* {@link HttpServletResponse} methods or through a charset parameter on the
|
||||
* {@code Content-Type}.
|
||||
* {@code Content-Type}. If no charset has been explicitly defined, the default
|
||||
* character encoding will be used.
|
||||
* @return the content as a {@code String}
|
||||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @see #getContentAsString(Charset)
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #setContentType(String)
|
||||
*/
|
||||
public String getContentAsString() throws UnsupportedEncodingException {
|
||||
return (this.characterEncoding != null ?
|
||||
this.content.toString(this.characterEncoding) : this.content.toString());
|
||||
return this.content.toString(getCharacterEncoding());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,11 +251,12 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @since 5.2
|
||||
* @see #getContentAsString()
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #setContentType(String)
|
||||
*/
|
||||
public String getContentAsString(Charset fallbackCharset) throws UnsupportedEncodingException {
|
||||
return (isCharset() && this.characterEncoding != null ?
|
||||
this.content.toString(this.characterEncoding) :
|
||||
this.content.toString(fallbackCharset.name()));
|
||||
String charsetName = (this.characterEncodingSet ? getCharacterEncoding() : fallbackCharset.name());
|
||||
return this.content.toString(charsetName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -282,16 +286,14 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
try {
|
||||
MediaType mediaType = MediaType.parseMediaType(contentType);
|
||||
if (mediaType.getCharset() != null) {
|
||||
this.characterEncoding = mediaType.getCharset().name();
|
||||
this.characterEncodingSet = true;
|
||||
setExplicitCharacterEncoding(mediaType.getCharset().name());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Try to get charset value anyway
|
||||
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
|
||||
if (charsetIndex != -1) {
|
||||
this.characterEncoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
|
||||
this.characterEncodingSet = true;
|
||||
setExplicitCharacterEncoding(contentType.substring(charsetIndex + CHARSET_PREFIX.length()));
|
||||
}
|
||||
}
|
||||
updateContentTypePropertyAndHeader();
|
||||
|
@ -344,7 +346,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
@Override
|
||||
public void reset() {
|
||||
resetBuffer();
|
||||
this.characterEncoding = null;
|
||||
this.characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||
this.characterEncodingSet = false;
|
||||
this.contentLength = 0;
|
||||
this.contentType = null;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -248,14 +248,11 @@ public class PrintingResultHandler implements ResultHandler {
|
|||
* Print the response.
|
||||
*/
|
||||
protected void printResponse(MockHttpServletResponse response) throws Exception {
|
||||
String body = (response.getCharacterEncoding() != null ?
|
||||
response.getContentAsString() : MISSING_CHARACTER_ENCODING);
|
||||
|
||||
this.printer.printValue("Status", response.getStatus());
|
||||
this.printer.printValue("Error message", response.getErrorMessage());
|
||||
this.printer.printValue("Headers", getResponseHeaders(response));
|
||||
this.printer.printValue("Content type", response.getContentType());
|
||||
this.printer.printValue("Body", body);
|
||||
this.printer.printValue("Body", response.getContentAsString());
|
||||
this.printer.printValue("Forwarded URL", response.getForwardedUrl());
|
||||
this.printer.printValue("Redirected URL", response.getRedirectedUrl());
|
||||
printCookies(response.getCookies());
|
||||
|
|
|
@ -551,6 +551,8 @@ class MockHttpServletResponseTests {
|
|||
|
||||
@Test // gh-25501
|
||||
void resetResetsCharset() {
|
||||
assertThat(response.getContentType()).isNull();
|
||||
assertThat(response.getCharacterEncoding()).isEqualTo("ISO-8859-1");
|
||||
assertThat(response.isCharset()).isFalse();
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
assertThat(response.isCharset()).isTrue();
|
||||
|
@ -562,6 +564,8 @@ class MockHttpServletResponseTests {
|
|||
|
||||
response.reset();
|
||||
|
||||
assertThat(response.getContentType()).isNull();
|
||||
assertThat(response.getCharacterEncoding()).isEqualTo("ISO-8859-1");
|
||||
assertThat(response.isCharset()).isFalse();
|
||||
// Do not invoke setCharacterEncoding() since that sets the charset flag to true.
|
||||
// response.setCharacterEncoding("UTF-8");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -238,16 +238,6 @@ public class PrintingResultHandlerTests {
|
|||
assertValue("MockHttpServletResponse", "Body", "text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printResponseWithoutCharacterEncoding() throws Exception {
|
||||
this.response.setCharacterEncoding(null);
|
||||
this.response.getWriter().print("text");
|
||||
|
||||
this.handler.handle(this.mvcResult);
|
||||
|
||||
assertValue("MockHttpServletResponse", "Body", "<no character encoding set>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printHandlerNull() throws Exception {
|
||||
StubMvcResult mvcResult = new StubMvcResult(this.request, null, null, null, null, null, this.response);
|
||||
|
|
|
@ -80,7 +80,6 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
|
||||
private boolean writerAccessAllowed = true;
|
||||
|
||||
@Nullable
|
||||
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||
|
||||
/**
|
||||
|
@ -171,8 +170,8 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* Determine whether the character encoding has been explicitly set through
|
||||
* {@link HttpServletResponse} methods or through a {@code charset} parameter
|
||||
* on the {@code Content-Type}.
|
||||
* <p>If {@code false}, {@link #getCharacterEncoding()} will return a default
|
||||
* encoding value.
|
||||
* <p>If {@code false}, {@link #getCharacterEncoding()} will return the default
|
||||
* character encoding.
|
||||
*/
|
||||
public boolean isCharset() {
|
||||
return this.characterEncodingSet;
|
||||
|
@ -180,16 +179,21 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
|
||||
@Override
|
||||
public void setCharacterEncoding(String characterEncoding) {
|
||||
setExplicitCharacterEncoding(characterEncoding);
|
||||
updateContentTypePropertyAndHeader();
|
||||
}
|
||||
|
||||
private void setExplicitCharacterEncoding(String characterEncoding) {
|
||||
Assert.notNull(characterEncoding, "'characterEncoding' must not be null");
|
||||
this.characterEncoding = characterEncoding;
|
||||
this.characterEncodingSet = true;
|
||||
updateContentTypePropertyAndHeader();
|
||||
}
|
||||
|
||||
private void updateContentTypePropertyAndHeader() {
|
||||
if (this.contentType != null) {
|
||||
String value = this.contentType;
|
||||
if (this.characterEncodingSet && !this.contentType.toLowerCase().contains(CHARSET_PREFIX)) {
|
||||
value = value + ';' + CHARSET_PREFIX + this.characterEncoding;
|
||||
if (this.characterEncodingSet && !value.toLowerCase().contains(CHARSET_PREFIX)) {
|
||||
value += ';' + CHARSET_PREFIX + getCharacterEncoding();
|
||||
this.contentType = value;
|
||||
}
|
||||
doAddHeaderValue(HttpHeaders.CONTENT_TYPE, value, true);
|
||||
|
@ -197,7 +201,6 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getCharacterEncoding() {
|
||||
return this.characterEncoding;
|
||||
}
|
||||
|
@ -212,9 +215,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
||||
Assert.state(this.writerAccessAllowed, "Writer access not allowed");
|
||||
if (this.writer == null) {
|
||||
Writer targetWriter = (this.characterEncoding != null ?
|
||||
new OutputStreamWriter(this.content, this.characterEncoding) :
|
||||
new OutputStreamWriter(this.content));
|
||||
Writer targetWriter = new OutputStreamWriter(this.content, getCharacterEncoding());
|
||||
this.writer = new ResponsePrintWriter(targetWriter);
|
||||
}
|
||||
return this.writer;
|
||||
|
@ -228,14 +229,16 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* Get the content of the response body as a {@code String}, using the charset
|
||||
* specified for the response by the application, either through
|
||||
* {@link HttpServletResponse} methods or through a charset parameter on the
|
||||
* {@code Content-Type}.
|
||||
* {@code Content-Type}. If no charset has been explicitly defined, the default
|
||||
* character encoding will be used.
|
||||
* @return the content as a {@code String}
|
||||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @see #getContentAsString(Charset)
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #setContentType(String)
|
||||
*/
|
||||
public String getContentAsString() throws UnsupportedEncodingException {
|
||||
return (this.characterEncoding != null ?
|
||||
this.content.toString(this.characterEncoding) : this.content.toString());
|
||||
return this.content.toString(getCharacterEncoding());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -248,11 +251,12 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @since 5.2
|
||||
* @see #getContentAsString()
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #setContentType(String)
|
||||
*/
|
||||
public String getContentAsString(Charset fallbackCharset) throws UnsupportedEncodingException {
|
||||
return (isCharset() && this.characterEncoding != null ?
|
||||
this.content.toString(this.characterEncoding) :
|
||||
this.content.toString(fallbackCharset.name()));
|
||||
String charsetName = (this.characterEncodingSet ? getCharacterEncoding() : fallbackCharset.name());
|
||||
return this.content.toString(charsetName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -282,16 +286,14 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
try {
|
||||
MediaType mediaType = MediaType.parseMediaType(contentType);
|
||||
if (mediaType.getCharset() != null) {
|
||||
this.characterEncoding = mediaType.getCharset().name();
|
||||
this.characterEncodingSet = true;
|
||||
setExplicitCharacterEncoding(mediaType.getCharset().name());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Try to get charset value anyway
|
||||
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
|
||||
if (charsetIndex != -1) {
|
||||
this.characterEncoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
|
||||
this.characterEncodingSet = true;
|
||||
setExplicitCharacterEncoding(contentType.substring(charsetIndex + CHARSET_PREFIX.length()));
|
||||
}
|
||||
}
|
||||
updateContentTypePropertyAndHeader();
|
||||
|
@ -344,7 +346,7 @@ public class MockHttpServletResponse implements HttpServletResponse {
|
|||
@Override
|
||||
public void reset() {
|
||||
resetBuffer();
|
||||
this.characterEncoding = null;
|
||||
this.characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||
this.characterEncodingSet = false;
|
||||
this.contentLength = 0;
|
||||
this.contentType = null;
|
||||
|
|
Loading…
Reference in New Issue