From 5b901852e6ee6048d7d2e243dafe4b3c8d533ad8 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 14 Nov 2015 15:32:42 +0100 Subject: [PATCH] Upgrade to HtmlUnit 2.19 This upgrade includes AutoCloseable support for HtmlUnit WebConnections as introduced in 2.19, while remaining compatible with 2.18. Issue: SPR-13686 --- build.gradle | 4 +-- .../htmlunit/DelegatingWebConnection.java | 20 ++++++----- .../htmlunit/ForwardRequestPostProcessor.java | 2 +- .../htmlunit/HtmlUnitRequestBuilder.java | 16 ++++----- .../htmlunit/MockMvcWebClientBuilder.java | 9 ++--- .../htmlunit/MockMvcWebConnection.java | 36 +++++++++++-------- .../MockMvcWebConnectionBuilderSupport.java | 11 +++--- .../htmlunit/MockWebResponseBuilder.java | 18 +++++----- .../MockMvcHtmlUnitDriverBuilder.java | 13 +++---- .../WebConnectionHtmlUnitDriver.java | 10 +++--- 10 files changed, 76 insertions(+), 63 deletions(-) diff --git a/build.gradle b/build.gradle index 509c99090c..3f1d8d2685 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ configure(allprojects) { project -> ext.hibval4Version = "4.3.2.Final" ext.hibval5Version = "5.2.2.Final" ext.hsqldbVersion = "2.3.3" - ext.htmlunitVersion = "2.18" + ext.htmlunitVersion = "2.19" ext.httpasyncVersion = "4.1.1" ext.httpclientVersion = "4.5.1" ext.jackson2Version = "2.6.3" @@ -66,7 +66,7 @@ configure(allprojects) { project -> ext.reactorVersion = "2.0.7.RELEASE" ext.romeVersion = "1.5.1" ext.seleniumVersion = "2.48.2" - ext.slf4jVersion = "1.7.12" + ext.slf4jVersion = "1.7.13" ext.snakeyamlVersion = "1.16" ext.snifferVersion = "1.14" ext.testngVersion = "6.9.9" diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnection.java index 1fc2e17670..091681a86d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnection.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/DelegatingWebConnection.java @@ -20,12 +20,12 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; -import org.springframework.util.Assert; - import com.gargoylesoftware.htmlunit.WebConnection; import com.gargoylesoftware.htmlunit.WebRequest; import com.gargoylesoftware.htmlunit.WebResponse; +import org.springframework.util.Assert; + /** * Implementation of {@link WebConnection} that allows delegating to various * {@code WebConnection} implementations. @@ -62,8 +62,8 @@ public final class DelegatingWebConnection implements WebConnection { public DelegatingWebConnection(WebConnection defaultConnection, List connections) { - Assert.notNull(defaultConnection, "defaultConnection must not be null"); - Assert.notEmpty(connections, "connections must not be empty"); + Assert.notNull(defaultConnection, "Default WebConnection must not be null"); + Assert.notEmpty(connections, "Connections List must not be empty"); this.connections = connections; this.defaultConnection = defaultConnection; } @@ -72,6 +72,7 @@ public final class DelegatingWebConnection implements WebConnection { this(defaultConnection, Arrays.asList(connections)); } + @Override public WebResponse getResponse(WebRequest request) throws IOException { for (DelegateWebConnection connection : this.connections) { @@ -82,6 +83,10 @@ public final class DelegatingWebConnection implements WebConnection { return this.defaultConnection.getResponse(request); } + @Override + public void close() { + } + public static final class DelegateWebConnection { @@ -89,19 +94,18 @@ public final class DelegatingWebConnection implements WebConnection { private final WebConnection delegate; - public DelegateWebConnection(WebRequestMatcher matcher, WebConnection delegate) { this.matcher = matcher; this.delegate = delegate; } private WebRequestMatcher getMatcher() { - return matcher; + return this.matcher; } private WebConnection getDelegate() { - return delegate; + return this.delegate; } } -} \ No newline at end of file +} diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/ForwardRequestPostProcessor.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/ForwardRequestPostProcessor.java index 75284bf447..f6bc223140 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/ForwardRequestPostProcessor.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/ForwardRequestPostProcessor.java @@ -31,7 +31,7 @@ final class ForwardRequestPostProcessor implements RequestPostProcessor { public ForwardRequestPostProcessor(String forwardUrl) { - Assert.hasText(forwardUrl, "forwardUrl must not be null or empty"); + Assert.hasText(forwardUrl, "Forward URL must not be null or empty"); this.forwardUrl = forwardUrl; } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java index 2d2802f94e..3cd0218a13 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java @@ -34,6 +34,11 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import com.gargoylesoftware.htmlunit.CookieManager; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.WebRequest; +import com.gargoylesoftware.htmlunit.util.NameValuePair; + import org.springframework.beans.Mergeable; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; @@ -46,11 +51,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; -import com.gargoylesoftware.htmlunit.CookieManager; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebRequest; -import com.gargoylesoftware.htmlunit.util.NameValuePair; - /** * Internal class used to transform a {@link WebRequest} into a * {@link MockHttpServletRequest} using Spring MVC Test's {@link RequestBuilder}. @@ -91,9 +91,9 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable { * {@link MockHttpServletRequest}; never {@code null} */ public HtmlUnitRequestBuilder(Map sessions, WebClient webClient, WebRequest webRequest) { - Assert.notNull(sessions, "sessions map must not be null"); - Assert.notNull(webClient, "webClient must not be null"); - Assert.notNull(webRequest, "webRequest must not be null"); + Assert.notNull(sessions, "Sessions Map must not be null"); + Assert.notNull(webClient, "WebClient must not be null"); + Assert.notNull(webRequest, "WebRequest must not be null"); this.sessions = sessions; this.webClient = webClient; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilder.java index 0806db7979..5dc12a2118 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebClientBuilder.java @@ -16,13 +16,13 @@ package org.springframework.test.web.servlet.htmlunit; +import com.gargoylesoftware.htmlunit.WebClient; + import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcConfigurer; import org.springframework.util.Assert; import org.springframework.web.context.WebApplicationContext; -import com.gargoylesoftware.htmlunit.WebClient; - /** * {@code MockMvcWebClientBuilder} simplifies the creation of an HtmlUnit * {@link WebClient} that delegates to a {@link MockMvc} instance. @@ -57,6 +57,7 @@ public class MockMvcWebClientBuilder extends MockMvcWebConnectionBuilderSupport< super(context, configurer); } + /** * Create a new {@code MockMvcWebClientBuilder} based on the supplied * {@link MockMvc} instance. @@ -104,7 +105,7 @@ public class MockMvcWebClientBuilder extends MockMvcWebConnectionBuilderSupport< * @see #build() */ public MockMvcWebClientBuilder withDelegate(WebClient webClient) { - Assert.notNull(webClient, "webClient must not be null"); + Assert.notNull(webClient, "WebClient must not be null"); webClient.setWebConnection(createConnection(webClient.getWebConnection())); this.webClient = webClient; return this; @@ -125,4 +126,4 @@ public class MockMvcWebClientBuilder extends MockMvcWebConnectionBuilderSupport< return (this.webClient != null ? this.webClient : withDelegate(new WebClient()).build()); } -} \ No newline at end of file +} diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java index 004b5a82cf..d7a6fe6087 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java @@ -20,6 +20,11 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.WebConnection; +import com.gargoylesoftware.htmlunit.WebRequest; +import com.gargoylesoftware.htmlunit.WebResponse; + import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; import org.springframework.test.web.servlet.MockMvc; @@ -27,11 +32,6 @@ import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.ResultActions; import org.springframework.util.Assert; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebConnection; -import com.gargoylesoftware.htmlunit.WebRequest; -import com.gargoylesoftware.htmlunit.WebResponse; - /** * {@code MockMvcWebConnection} enables {@link MockMvc} to transform a * {@link WebRequest} into a {@link WebResponse}. @@ -86,7 +86,7 @@ public final class MockMvcWebConnection implements WebConnection { * @param contextPath the contextPath to use */ public MockMvcWebConnection(MockMvc mockMvc, String contextPath) { - Assert.notNull(mockMvc, "mockMvc must not be null"); + Assert.notNull(mockMvc, "MockMvc must not be null"); validateContextPath(contextPath); this.webClient = new WebClient(); @@ -94,13 +94,19 @@ public final class MockMvcWebConnection implements WebConnection { this.contextPath = contextPath; } + + public void setWebClient(WebClient webClient) { + Assert.notNull(webClient, "WebClient must not be null"); + this.webClient = webClient; + } + + public WebResponse getResponse(WebRequest webRequest) throws IOException { long startTime = System.currentTimeMillis(); HtmlUnitRequestBuilder requestBuilder = new HtmlUnitRequestBuilder(this.sessions, this.webClient, webRequest); requestBuilder.setContextPath(this.contextPath); MockHttpServletResponse httpServletResponse = getResponse(requestBuilder); - String forwardedUrl = httpServletResponse.getForwardedUrl(); while (forwardedUrl != null) { requestBuilder.setForwardPostProcessor(new ForwardRequestPostProcessor(forwardedUrl)); @@ -111,23 +117,23 @@ public final class MockMvcWebConnection implements WebConnection { return new MockWebResponseBuilder(startTime, webRequest, httpServletResponse).build(); } - public void setWebClient(WebClient webClient) { - Assert.notNull(webClient, "webClient must not be null"); - this.webClient = webClient; - } - private MockHttpServletResponse getResponse(RequestBuilder requestBuilder) throws IOException { ResultActions resultActions; try { resultActions = this.mockMvc.perform(requestBuilder); } - catch (Exception e) { - throw (IOException) new IOException(e.getMessage()).initCause(e); + catch (Exception ex) { + throw new IOException(ex); } return resultActions.andReturn().getResponse(); } + @Override + public void close() { + } + + /** * Validate the supplied {@code contextPath}. *

If the value is not {@code null}, it must conform to @@ -148,4 +154,4 @@ public final class MockMvcWebConnection implements WebConnection { } } -} \ No newline at end of file +} diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionBuilderSupport.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionBuilderSupport.java index 10bedebaf4..6575e6a26e 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionBuilderSupport.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionBuilderSupport.java @@ -19,14 +19,14 @@ package org.springframework.test.web.servlet.htmlunit; import java.util.ArrayList; import java.util.List; +import com.gargoylesoftware.htmlunit.WebConnection; + import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.test.web.servlet.setup.MockMvcConfigurer; import org.springframework.util.Assert; import org.springframework.web.context.WebApplicationContext; -import com.gargoylesoftware.htmlunit.WebConnection; - /** * Support class that simplifies the creation of a {@link WebConnection} that * uses {@link MockMvc} and optionally delegates to a real {@link WebConnection} @@ -55,7 +55,7 @@ public abstract class MockMvcWebConnectionBuilderSupportIf the supplied value is {@code null} or empty, the first path @@ -146,7 +147,7 @@ public abstract class MockMvcWebConnectionBuilderSupport responseHeaders = responseHeaders(); - int statusCode = (this.response.getRedirectedUrl() != null ? HttpStatus.MOVED_PERMANENTLY.value() - : this.response.getStatus()); + int statusCode = (this.response.getRedirectedUrl() != null ? + HttpStatus.MOVED_PERMANENTLY.value() : this.response.getStatus()); String statusMessage = statusMessage(statusCode); return new WebResponseData(this.response.getContentAsByteArray(), statusCode, statusMessage, responseHeaders); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilder.java index 43e513d6ca..3b8ded7168 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/MockMvcHtmlUnitDriverBuilder.java @@ -16,6 +16,8 @@ package org.springframework.test.web.servlet.htmlunit.webdriver; +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.WebClient; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.springframework.test.web.servlet.MockMvc; @@ -25,9 +27,6 @@ import org.springframework.test.web.servlet.setup.MockMvcConfigurer; import org.springframework.util.Assert; import org.springframework.web.context.WebApplicationContext; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.WebClient; - /** * {@code MockMvcHtmlUnitDriverBuilder} simplifies the building of an * {@link HtmlUnitDriver} that delegates to {@link MockMvc} and optionally @@ -66,6 +65,7 @@ public class MockMvcHtmlUnitDriverBuilder extends MockMvcWebConnectionBuilderSup super(context, configurer); } + /** * Create a new {@code MockMvcHtmlUnitDriverBuilder} based on the supplied * {@link MockMvc} instance. @@ -99,6 +99,7 @@ public class MockMvcHtmlUnitDriverBuilder extends MockMvcWebConnectionBuilderSup */ public static MockMvcHtmlUnitDriverBuilder webAppContextSetup(WebApplicationContext context, MockMvcConfigurer configurer) { + Assert.notNull(context, "WebApplicationContext must not be null"); Assert.notNull(configurer, "MockMvcConfigurer must not be null"); return new MockMvcHtmlUnitDriverBuilder(context, configurer); @@ -126,7 +127,7 @@ public class MockMvcHtmlUnitDriverBuilder extends MockMvcWebConnectionBuilderSup * @see #build() */ public MockMvcHtmlUnitDriverBuilder withDelegate(WebConnectionHtmlUnitDriver driver) { - Assert.notNull(driver, "driver must not be null"); + Assert.notNull(driver, "HtmlUnitDriver must not be null"); driver.setJavascriptEnabled(this.javascriptEnabled); driver.setWebConnection(createConnection(driver.getWebConnection())); this.driver = driver; @@ -146,8 +147,8 @@ public class MockMvcHtmlUnitDriverBuilder extends MockMvcWebConnectionBuilderSup * @see #withDelegate(WebConnectionHtmlUnitDriver) */ public HtmlUnitDriver build() { - return (this.driver != null ? this.driver - : withDelegate(new WebConnectionHtmlUnitDriver(BrowserVersion.CHROME)).build()); + return (this.driver != null ? this.driver : + withDelegate(new WebConnectionHtmlUnitDriver(BrowserVersion.CHROME)).build()); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java index f0960d727c..ab04baf253 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java @@ -16,15 +16,14 @@ package org.springframework.test.web.servlet.htmlunit.webdriver; +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.WebConnection; import org.openqa.selenium.Capabilities; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.springframework.util.Assert; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.WebClient; -import com.gargoylesoftware.htmlunit.WebConnection; - /** * {@code WebConnectionHtmlUnitDriver} enables configuration of the * {@link WebConnection} for an {@link HtmlUnitDriver} instance. @@ -58,6 +57,7 @@ public class WebConnectionHtmlUnitDriver extends HtmlUnitDriver { super(capabilities); } + /** * Modify the supplied {@link WebClient} and retain a reference to it * so that its {@link WebConnection} is {@linkplain #getWebConnection @@ -107,4 +107,4 @@ public class WebConnectionHtmlUnitDriver extends HtmlUnitDriver { this.webClient.setWebConnection(webConnection); } -} \ No newline at end of file +} -- GitLab