Only print request/response body if char enc is present in MVC Test
Commit e65a1a4372 introduced support in PrintingResultHandler for only
printing the request or response body in the Spring MVC Test framework
if the content type is known to be text-based (e.g., plain text, HTML,
XHTML, XML, JSON, etc.). For unknown content types the body is assumed
to be text-based and is therefore always printed. The latter behavior,
however, is undesirable since the content may in fact not be text-based.
This commit addresses this issue by making the printing of the request
or response body an opt-in feature. Specifically, if a character
encoding has been set, the request or response body will be printed by
the PrintingResultHandler. Note, however, that the character encoding
is set to ISO-8859-1 in MockHttpServletResponse by default.
In addition, MockHttpServletRequest's getContentAsString() method now
throws an IllegalStateException if the character encoding has not been
set.
Issue: SPR-14776
This commit is contained in:
parent
69116c2acc
commit
8cf1933148
|
|
@ -373,6 +373,10 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Set the content of the request body as a byte array.
|
||||
* <p>If the supplied byte array represents text such as XML or JSON, the
|
||||
* {@link #setCharacterEncoding character encoding} should typically be
|
||||
* set as well.
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #getContentAsByteArray()
|
||||
* @see #getContentAsString()
|
||||
*/
|
||||
|
|
@ -382,6 +386,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Get the content of the request body as a byte array.
|
||||
* @return the content as a byte array, potentially {@code null}
|
||||
* @since 5.0
|
||||
* @see #setContent(byte[])
|
||||
* @see #getContentAsString()
|
||||
|
|
@ -392,19 +397,24 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Get the content of the request body as a {@code String}, using the configured
|
||||
* {@linkplain #getCharacterEncoding character encoding} if present.
|
||||
* {@linkplain #getCharacterEncoding character encoding}.
|
||||
* @return the content as a {@code String}, potentially {@code null}
|
||||
* @throws IllegalStateException if the character encoding has not been set
|
||||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @since 5.0
|
||||
* @see #setContent(byte[])
|
||||
* @see #getContentAsByteArray()
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #getContentAsByteArray()
|
||||
*/
|
||||
public String getContentAsString() throws UnsupportedEncodingException {
|
||||
public String getContentAsString() throws IllegalStateException, UnsupportedEncodingException {
|
||||
Assert.state(this.characterEncoding != null,
|
||||
"Cannot get content as a String for a null character encoding. " +
|
||||
"Consider setting the characterEncoding in the request.");
|
||||
|
||||
if (this.content == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (this.characterEncoding != null ?
|
||||
new String(this.content, this.characterEncoding) : new String(this.content));
|
||||
return new String(this.content, this.characterEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@
|
|||
|
||||
package org.springframework.test.web.servlet.result;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
|
@ -31,8 +29,6 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
|||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultHandler;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
|
@ -58,12 +54,7 @@ import org.springframework.web.servlet.support.RequestContextUtils;
|
|||
*/
|
||||
public class PrintingResultHandler implements ResultHandler {
|
||||
|
||||
private static final String NOT_PRINTABLE = "<content type is not printable text>";
|
||||
|
||||
private static final List<MimeType> printableMimeTypes = Arrays.asList(
|
||||
MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.APPLICATION_XML,
|
||||
new MimeType("text", "*"), new MimeType("application", "*+json"),
|
||||
new MimeType("application", "*+xml"));
|
||||
private static final String MISSING_CHARACTER_ENCODING = "<no character encoding set>";
|
||||
|
||||
|
||||
private final ResultValuePrinter printer;
|
||||
|
|
@ -115,8 +106,8 @@ public class PrintingResultHandler implements ResultHandler {
|
|||
* Print the request.
|
||||
*/
|
||||
protected void printRequest(MockHttpServletRequest request) throws Exception {
|
||||
String body = (isPrintableContentType(request.getContentType()) ?
|
||||
request.getContentAsString() : NOT_PRINTABLE);
|
||||
String body = (request.getCharacterEncoding() != null ?
|
||||
request.getContentAsString() : MISSING_CHARACTER_ENCODING);
|
||||
|
||||
this.printer.printValue("HTTP Method", request.getMethod());
|
||||
this.printer.printValue("Request URI", request.getRequestURI());
|
||||
|
|
@ -238,8 +229,8 @@ public class PrintingResultHandler implements ResultHandler {
|
|||
* Print the response.
|
||||
*/
|
||||
protected void printResponse(MockHttpServletResponse response) throws Exception {
|
||||
String body = (isPrintableContentType(response.getContentType()) ?
|
||||
response.getContentAsString() : NOT_PRINTABLE);
|
||||
String body = (response.getCharacterEncoding() != null ?
|
||||
response.getContentAsString() : MISSING_CHARACTER_ENCODING);
|
||||
|
||||
this.printer.printValue("Status", response.getStatus());
|
||||
this.printer.printValue("Error message", response.getErrorMessage());
|
||||
|
|
@ -284,23 +275,6 @@ public class PrintingResultHandler implements ResultHandler {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine if the supplied content type is <em>printable</em> (i.e., text-based).
|
||||
* <p>If the supplied content type is {@code null} (i.e., unknown), this method
|
||||
* assumes that the content is printable by default and returns {@code true}.
|
||||
* @param contentType the content type to check; {@code null} if unknown
|
||||
* @return {@code true} if the content type is known to be or assumed to be printable
|
||||
* @since 5.0
|
||||
*/
|
||||
private static boolean isPrintableContentType(String contentType) {
|
||||
if (contentType == null) {
|
||||
return true;
|
||||
}
|
||||
MimeType mimeType = MimeType.valueOf(contentType);
|
||||
return printableMimeTypes.stream().anyMatch(printable -> printable.includes(mimeType));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A contract for how to actually write result information.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ import java.util.Map;
|
|||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
|
|
@ -54,7 +56,10 @@ public class MockHttpServletRequestTests {
|
|||
|
||||
private static final String IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
|
||||
private MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
@Rule
|
||||
public final ExpectedException exception = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
|
|
@ -76,13 +81,10 @@ public class MockHttpServletRequestTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void setContentAndGetContentAsStringWithDefaultCharacterEncoding() throws IOException {
|
||||
String palindrome = "ablE was I ere I saw Elba";
|
||||
byte[] bytes = palindrome.getBytes();
|
||||
request.setContent(bytes);
|
||||
assertEquals(bytes.length, request.getContentLength());
|
||||
assertNotNull(request.getContentAsString());
|
||||
assertEquals(palindrome, request.getContentAsString());
|
||||
public void getContentAsStringWithoutSettingCharacterEncoding() throws IOException {
|
||||
exception.expect(IllegalStateException.class);
|
||||
exception.expectMessage("Cannot get content as a String for a null character encoding");
|
||||
request.getContentAsString();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -102,7 +104,6 @@ public class MockHttpServletRequestTests {
|
|||
assertNotNull(request.getInputStream());
|
||||
assertEquals(-1, request.getInputStream().read());
|
||||
assertNull(request.getContentAsByteArray());
|
||||
assertNull(request.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@
|
|||
package org.springframework.test.web.servlet.result;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
|
@ -33,7 +31,6 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
|||
import org.springframework.test.web.servlet.StubMvcResult;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.BindingResult;
|
||||
|
|
@ -53,11 +50,6 @@ import static org.junit.Assert.*;
|
|||
*/
|
||||
public class PrintingResultHandlerTests {
|
||||
|
||||
private static final List<String> textContentTypes = Arrays.asList(MimeTypeUtils.APPLICATION_JSON_VALUE,
|
||||
MimeTypeUtils.APPLICATION_XML_VALUE, MimeTypeUtils.APPLICATION_XHTML_XML_VALUE,
|
||||
MimeTypeUtils.TEXT_HTML_VALUE, MimeTypeUtils.TEXT_PLAIN_VALUE);
|
||||
|
||||
|
||||
private final TestPrintingResultHandler handler = new TestPrintingResultHandler();
|
||||
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/") {
|
||||
|
|
@ -147,43 +139,48 @@ public class PrintingResultHandlerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void printRequestWithTextContentTypes() throws Exception {
|
||||
this.request.setContent("text".getBytes());
|
||||
public void printRequestWithCharacterEncoding() throws Exception {
|
||||
this.request.setCharacterEncoding("UTF-8");
|
||||
this.request.setContent("text".getBytes("UTF-8"));
|
||||
|
||||
for (String contentType: textContentTypes) {
|
||||
this.request.setContentType(contentType);
|
||||
this.handler.handle(this.mvcResult);
|
||||
assertValue("MockHttpServletRequest", "Body", "text");
|
||||
}
|
||||
this.handler.handle(this.mvcResult);
|
||||
|
||||
assertValue("MockHttpServletRequest", "Body", "text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printResponseWithTextContentTypes() throws Exception {
|
||||
public void printRequestWithoutCharacterEncoding() throws Exception {
|
||||
this.handler.handle(this.mvcResult);
|
||||
|
||||
assertValue("MockHttpServletRequest", "Body", "<no character encoding set>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printResponseWithCharacterEncoding() throws Exception {
|
||||
this.response.setCharacterEncoding("UTF-8");
|
||||
this.response.getWriter().print("text");
|
||||
|
||||
for (String contentType: textContentTypes) {
|
||||
this.response.setContentType(contentType);
|
||||
this.handler.handle(this.mvcResult);
|
||||
assertValue("MockHttpServletResponse", "Body", "text");
|
||||
}
|
||||
this.handler.handle(this.mvcResult);
|
||||
assertValue("MockHttpServletResponse", "Body", "text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printRequestWithBinaryContentType() throws Exception {
|
||||
this.request.setContentType(MimeTypeUtils.IMAGE_JPEG_VALUE);
|
||||
public void printResponseWithDefaultCharacterEncoding() throws Exception {
|
||||
this.response.getWriter().print("text");
|
||||
|
||||
this.handler.handle(this.mvcResult);
|
||||
|
||||
assertValue("MockHttpServletRequest", "Body", "<content type is not printable text>");
|
||||
assertValue("MockHttpServletResponse", "Body", "text");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printResponseWithBinaryContentType() throws Exception {
|
||||
this.response.setContentType(MimeTypeUtils.IMAGE_JPEG_VALUE);
|
||||
public void printResponseWithoutCharacterEncoding() throws Exception {
|
||||
this.response.setCharacterEncoding(null);
|
||||
this.response.getWriter().print("text");
|
||||
|
||||
this.handler.handle(this.mvcResult);
|
||||
|
||||
assertValue("MockHttpServletResponse", "Body", "<content type is not printable text>");
|
||||
assertValue("MockHttpServletResponse", "Body", "<no character encoding set>");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -373,6 +373,10 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Set the content of the request body as a byte array.
|
||||
* <p>If the supplied byte array represents text such as XML or JSON, the
|
||||
* {@link #setCharacterEncoding character encoding} should typically be
|
||||
* set as well.
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #getContentAsByteArray()
|
||||
* @see #getContentAsString()
|
||||
*/
|
||||
|
|
@ -382,6 +386,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Get the content of the request body as a byte array.
|
||||
* @return the content as a byte array, potentially {@code null}
|
||||
* @since 5.0
|
||||
* @see #setContent(byte[])
|
||||
* @see #getContentAsString()
|
||||
|
|
@ -392,19 +397,24 @@ public class MockHttpServletRequest implements HttpServletRequest {
|
|||
|
||||
/**
|
||||
* Get the content of the request body as a {@code String}, using the configured
|
||||
* {@linkplain #getCharacterEncoding character encoding} if present.
|
||||
* {@linkplain #getCharacterEncoding character encoding}.
|
||||
* @return the content as a {@code String}, potentially {@code null}
|
||||
* @throws IllegalStateException if the character encoding has not been set
|
||||
* @throws UnsupportedEncodingException if the character encoding is not supported
|
||||
* @since 5.0
|
||||
* @see #setContent(byte[])
|
||||
* @see #getContentAsByteArray()
|
||||
* @see #setCharacterEncoding(String)
|
||||
* @see #getContentAsByteArray()
|
||||
*/
|
||||
public String getContentAsString() throws UnsupportedEncodingException {
|
||||
public String getContentAsString() throws IllegalStateException, UnsupportedEncodingException {
|
||||
Assert.state(this.characterEncoding != null,
|
||||
"Cannot get content as a String for a null character encoding. " +
|
||||
"Consider setting the characterEncoding in the request.");
|
||||
|
||||
if (this.content == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (this.characterEncoding != null ?
|
||||
new String(this.content, this.characterEncoding) : new String(this.content));
|
||||
return new String(this.content, this.characterEncoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in New Issue