diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java index 9c04f4deb4..89a4ce4c7a 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/PrintingResultHandler.java @@ -16,7 +16,9 @@ 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; @@ -29,6 +31,8 @@ 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; @@ -54,6 +58,14 @@ import org.springframework.web.servlet.support.RequestContextUtils; */ public class PrintingResultHandler implements ResultHandler { + private static final String NOT_PRINTABLE = ""; + + private static final List printableMimeTypes = Arrays.asList( + MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.APPLICATION_XML, + new MimeType("text", "*"), new MimeType("application", "*+json"), + new MimeType("application", "*+xml")); + + private final ResultValuePrinter printer; @@ -103,11 +115,14 @@ public class PrintingResultHandler implements ResultHandler { * Print the request. */ protected void printRequest(MockHttpServletRequest request) throws Exception { + String body = (isPrintableContentType(request.getContentType()) ? + request.getContentAsString() : NOT_PRINTABLE); + this.printer.printValue("HTTP Method", request.getMethod()); this.printer.printValue("Request URI", request.getRequestURI()); this.printer.printValue("Parameters", getParamsMultiValueMap(request)); this.printer.printValue("Headers", getRequestHeaders(request)); - this.printer.printValue("Body", request.getContentAsString()); + this.printer.printValue("Body", body); } protected final HttpHeaders getRequestHeaders(MockHttpServletRequest request) { @@ -223,11 +238,14 @@ public class PrintingResultHandler implements ResultHandler { * Print the response. */ protected void printResponse(MockHttpServletResponse response) throws Exception { + String body = (isPrintableContentType(response.getContentType()) ? + response.getContentAsString() : NOT_PRINTABLE); + 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", response.getContentAsString()); + this.printer.printValue("Body", body); this.printer.printValue("Forwarded URL", response.getForwardedUrl()); this.printer.printValue("Redirected URL", response.getRedirectedUrl()); printCookies(response.getCookies()); @@ -266,6 +284,23 @@ public class PrintingResultHandler implements ResultHandler { } + /** + * Determine if the supplied content type is printable (i.e., text-based). + *

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. */ diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java index 31b60f1b2e..fcbb4129e3 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/result/PrintingResultHandlerTests.java @@ -17,7 +17,9 @@ 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; @@ -31,6 +33,7 @@ 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; @@ -50,6 +53,11 @@ import static org.junit.Assert.*; */ public class PrintingResultHandlerTests { + private static final List 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", "/") { @@ -82,7 +90,6 @@ public class PrintingResultHandlerTests { MultiValueMap params = new LinkedMultiValueMap<>(); params.add("param", "paramValue"); - assertValue("MockHttpServletRequest", "HTTP Method", this.request.getMethod()); assertValue("MockHttpServletRequest", "Request URI", this.request.getRequestURI()); assertValue("MockHttpServletRequest", "Parameters", params); @@ -139,6 +146,46 @@ public class PrintingResultHandlerTests { assertTrue(cookie2.endsWith("]")); } + @Test + public void printRequestWithTextContentTypes() throws Exception { + this.request.setContent("text".getBytes()); + + for (String contentType: textContentTypes) { + this.request.setContentType(contentType); + this.handler.handle(this.mvcResult); + assertValue("MockHttpServletRequest", "Body", "text"); + } + } + + @Test + public void printResponseWithTextContentTypes() throws Exception { + this.response.getWriter().print("text"); + + for (String contentType: textContentTypes) { + this.response.setContentType(contentType); + this.handler.handle(this.mvcResult); + assertValue("MockHttpServletResponse", "Body", "text"); + } + } + + @Test + public void printRequestWithBinaryContentType() throws Exception { + this.request.setContentType(MimeTypeUtils.IMAGE_JPEG_VALUE); + + this.handler.handle(this.mvcResult); + + assertValue("MockHttpServletRequest", "Body", ""); + } + + @Test + public void printResponseWithBinaryContentType() throws Exception { + this.response.setContentType(MimeTypeUtils.IMAGE_JPEG_VALUE); + + this.handler.handle(this.mvcResult); + + assertValue("MockHttpServletResponse", "Body", ""); + } + @Test public void printHandlerNull() throws Exception { StubMvcResult mvcResult = new StubMvcResult(this.request, null, null, null, null, null, this.response);