Skip to content

Commit 9de9761

Browse files
committed
Adapt to HtmlUnit 2.25 getCharset() return type at runtime
Issue: SPR-15319
1 parent 015e00b commit 9de9761

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/HtmlUnitRequestBuilder.java

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 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.
@@ -17,8 +17,10 @@
1717
package org.springframework.test.web.servlet.htmlunit;
1818

1919
import java.io.UnsupportedEncodingException;
20+
import java.lang.reflect.Method;
2021
import java.net.URL;
2122
import java.net.URLDecoder;
23+
import java.nio.charset.Charset;
2224
import java.util.ArrayList;
2325
import java.util.Enumeration;
2426
import java.util.List;
@@ -50,7 +52,9 @@
5052
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
5153
import org.springframework.test.web.servlet.request.RequestPostProcessor;
5254
import org.springframework.util.Assert;
55+
import org.springframework.util.ClassUtils;
5356
import org.springframework.util.ObjectUtils;
57+
import org.springframework.util.ReflectionUtils;
5458
import org.springframework.util.StringUtils;
5559
import org.springframework.web.util.UriComponents;
5660
import org.springframework.web.util.UriComponentsBuilder;
@@ -59,7 +63,7 @@
5963
* Internal class used to transform a {@link WebRequest} into a
6064
* {@link MockHttpServletRequest} using Spring MVC Test's {@link RequestBuilder}.
6165
*
62-
* <p>By default the first path segment of the URL is used as the contextPath.
66+
* <p>By default the first path segment of the URL is used as the context path.
6367
* To override this default see {@link #setContextPath(String)}.
6468
*
6569
* @author Rob Winch
@@ -71,6 +75,11 @@ final class HtmlUnitRequestBuilder implements RequestBuilder, Mergeable {
7175

7276
private static final Pattern LOCALE_PATTERN = Pattern.compile("^\\s*(\\w{2})(?:-(\\w{2}))?(?:;q=(\\d+\\.\\d+))?$");
7377

78+
private static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
79+
80+
81+
private static final Method getCharsetMethod = ClassUtils.getMethodIfAvailable(WebRequest.class, "getCharset");
82+
7483
private final Map<String, MockHttpSession> sessions;
7584

7685
private final WebClient webClient;
@@ -98,23 +107,23 @@ public HtmlUnitRequestBuilder(Map<String, MockHttpSession> sessions, WebClient w
98107
Assert.notNull(sessions, "Sessions Map must not be null");
99108
Assert.notNull(webClient, "WebClient must not be null");
100109
Assert.notNull(webRequest, "WebRequest must not be null");
101-
102110
this.sessions = sessions;
103111
this.webClient = webClient;
104112
this.webRequest = webRequest;
105113
}
106114

115+
107116
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
108-
String charset = getCharset();
117+
Charset charset = getCharset();
109118
String httpMethod = this.webRequest.getHttpMethod().name();
110119
UriComponents uriComponents = uriComponents();
111120

112121
MockHttpServletRequest request = new HtmlUnitMockHttpServletRequest(
113122
servletContext, httpMethod, uriComponents.getPath());
114123
parent(request, this.parentBuilder);
115-
request.setServerName(uriComponents.getHost()); // needs to be first for additional headers
124+
request.setServerName(uriComponents.getHost()); // needs to be first for additional headers
116125
authType(request);
117-
request.setCharacterEncoding(charset);
126+
request.setCharacterEncoding(charset.name());
118127
content(request, charset);
119128
contextPath(request, uriComponents);
120129
contentType(request);
@@ -132,6 +141,21 @@ public MockHttpServletRequest buildRequest(ServletContext servletContext) {
132141
return postProcess(request);
133142
}
134143

144+
private Charset getCharset() {
145+
if (getCharsetMethod != null) {
146+
Object value = ReflectionUtils.invokeMethod(getCharsetMethod, this.webRequest);
147+
if (value instanceof Charset) {
148+
// HtmlUnit 2.25: a Charset
149+
return (Charset) value;
150+
}
151+
else if (value != null) {
152+
// HtmlUnit up until 2.24: a String
153+
return Charset.forName(value.toString());
154+
}
155+
}
156+
return DEFAULT_CHARSET;
157+
}
158+
135159
private MockHttpServletRequest postProcess(MockHttpServletRequest request) {
136160
if (this.parentPostProcessor != null) {
137161
request = this.parentPostProcessor.postProcessRequest(request);
@@ -220,17 +244,12 @@ private void authType(MockHttpServletRequest request) {
220244
}
221245
}
222246

223-
private void content(MockHttpServletRequest request, String charset) {
247+
private void content(MockHttpServletRequest request, Charset charset) {
224248
String requestBody = this.webRequest.getRequestBody();
225249
if (requestBody == null) {
226250
return;
227251
}
228-
try {
229-
request.setContent(requestBody.getBytes(charset));
230-
}
231-
catch (UnsupportedEncodingException ex) {
232-
throw new IllegalStateException(ex);
233-
}
252+
request.setContent(requestBody.getBytes(charset));
234253
}
235254

236255
private void contentType(MockHttpServletRequest request) {
@@ -256,8 +275,8 @@ private void contextPath(MockHttpServletRequest request, UriComponents uriCompon
256275
}
257276
else {
258277
if (!uriComponents.getPath().startsWith(this.contextPath)) {
259-
throw new IllegalArgumentException(uriComponents.getPath() + " should start with contextPath " +
260-
this.contextPath);
278+
throw new IllegalArgumentException("\"" + uriComponents.getPath() +
279+
"\" should start with context path \"" + this.contextPath + "\"");
261280
}
262281
request.setContextPath(this.contextPath);
263282
}
@@ -273,7 +292,7 @@ private void cookies(MockHttpServletRequest request) {
273292
String cookieName = tokens.nextToken().trim();
274293
if (!tokens.hasMoreTokens()) {
275294
throw new IllegalArgumentException("Expected value for cookie name '" + cookieName +
276-
"'. Full cookie was " + cookieHeaderValue);
295+
"': full cookie header was [" + cookieHeaderValue + "]");
277296
}
278297
String cookieValue = tokens.nextToken().trim();
279298
processCookie(request, cookies, new Cookie(cookieName, cookieValue));
@@ -305,14 +324,6 @@ private void processCookie(MockHttpServletRequest request, List<Cookie> cookies,
305324
}
306325
}
307326

308-
private String getCharset() {
309-
String charset = this.webRequest.getCharset();
310-
if (charset == null) {
311-
return "ISO-8859-1";
312-
}
313-
return charset;
314-
}
315-
316327
private String header(String headerName) {
317328
return this.webRequest.getAdditionalHeaders().get(headerName);
318329
}
@@ -394,7 +405,7 @@ private String urlDecode(String value) {
394405
private Locale parseLocale(String locale) {
395406
Matcher matcher = LOCALE_PATTERN.matcher(locale);
396407
if (!matcher.matches()) {
397-
throw new IllegalArgumentException("Invalid locale " + locale);
408+
throw new IllegalArgumentException("Invalid locale value [" + locale + "]");
398409
}
399410
String language = matcher.group(1);
400411
String country = matcher.group(2);

0 commit comments

Comments
 (0)