Skip to content

Commit ad65119

Browse files
committed
Polish ServletUriComponentsBuilder
1 parent 7f11c1e commit ad65119

File tree

2 files changed

+76
-71
lines changed

2 files changed

+76
-71
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java

+30-25
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,18 @@ protected ServletUriComponentsBuilder() {
5252
}
5353

5454
/**
55-
* Prepare a builder from the host, port, scheme, and context path of
56-
* an HttpServletRequest.
55+
* Prepare a builder from the host, port, scheme, and context path of the
56+
* given HttpServletRequest.
5757
*/
5858
public static ServletUriComponentsBuilder fromContextPath(HttpServletRequest request) {
59-
String path = request.getContextPath();
60-
path = prependForwardedPrefix(request, path);
61-
ServletUriComponentsBuilder builder = fromRequest(request);
62-
builder.replacePath(path);
63-
builder.replaceQuery(null);
59+
ServletUriComponentsBuilder builder = initFromRequest(request);
60+
builder.replacePath(prependForwardedPrefix(request, request.getContextPath()));
6461
return builder;
6562
}
6663

6764
/**
6865
* Prepare a builder from the host, port, scheme, context path, and
69-
* servlet mapping of an HttpServletRequest. The results may vary depending
70-
* on the type of servlet mapping used.
66+
* servlet mapping of the given HttpServletRequest.
7167
*
7268
* <p>If the servlet is mapped by name, e.g. {@code "/main/*"}, the path
7369
* will end with "/main". If the servlet is mapped otherwise, e.g.
@@ -83,12 +79,12 @@ public static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest
8379
}
8480

8581
/**
86-
* Prepare a builder from the host, port, scheme, and path of
87-
* an HttpServletRequest.
82+
* Prepare a builder from the host, port, scheme, and path (but not the query)
83+
* of the HttpServletRequest.
8884
*/
8985
public static ServletUriComponentsBuilder fromRequestUri(HttpServletRequest request) {
90-
ServletUriComponentsBuilder builder = fromRequest(request);
91-
builder.replaceQuery(null);
86+
ServletUriComponentsBuilder builder = initFromRequest(request);
87+
builder.initPath(prependForwardedPrefix(request, request.getRequestURI()));
9288
return builder;
9389
}
9490

@@ -97,6 +93,16 @@ public static ServletUriComponentsBuilder fromRequestUri(HttpServletRequest requ
9793
* query string of an HttpServletRequest.
9894
*/
9995
public static ServletUriComponentsBuilder fromRequest(HttpServletRequest request) {
96+
ServletUriComponentsBuilder builder = initFromRequest(request);
97+
builder.initPath(prependForwardedPrefix(request, request.getRequestURI()));
98+
builder.query(request.getQueryString());
99+
return builder;
100+
}
101+
102+
/**
103+
* Initialize a builder with a scheme, host,and port (but not path and query).
104+
*/
105+
private static ServletUriComponentsBuilder initFromRequest(HttpServletRequest request) {
100106
String scheme = request.getScheme();
101107
String host = request.getServerName();
102108
int port = request.getServerPort();
@@ -126,20 +132,20 @@ public static ServletUriComponentsBuilder fromRequest(HttpServletRequest request
126132
scheme = protocolHeader;
127133
}
128134

129-
String path = request.getRequestURI();
130-
path = prependForwardedPrefix(request, path);
131-
132135
ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder();
133136
builder.scheme(scheme);
134137
builder.host(host);
135138
if (scheme.equals("http") && port != 80 || scheme.equals("https") && port != 443) {
136139
builder.port(port);
137140
}
138-
builder.initPath(path);
139-
builder.query(request.getQueryString());
140141
return builder;
141142
}
142143

144+
private void initPath(String path) {
145+
this.originalPath = path;
146+
replacePath(path);
147+
}
148+
143149
private static String prependForwardedPrefix(HttpServletRequest request, String path) {
144150
String prefix = request.getHeader("X-Forwarded-Prefix");
145151
if (StringUtils.hasText(prefix)) {
@@ -148,6 +154,9 @@ private static String prependForwardedPrefix(HttpServletRequest request, String
148154
return path;
149155
}
150156

157+
158+
// Alternative methods relying on RequestContextHolder to find the request
159+
151160
/**
152161
* Same as {@link #fromContextPath(HttpServletRequest)} except the
153162
* request is obtained through {@link RequestContextHolder}.
@@ -180,8 +189,9 @@ public static ServletUriComponentsBuilder fromCurrentRequest() {
180189
return fromRequest(getCurrentRequest());
181190
}
182191

192+
183193
/**
184-
* Obtain the request through {@link RequestContextHolder}.
194+
* Get the request through {@link RequestContextHolder}.
185195
*/
186196
protected static HttpServletRequest getCurrentRequest() {
187197
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
@@ -192,13 +202,8 @@ protected static HttpServletRequest getCurrentRequest() {
192202
return servletRequest;
193203
}
194204

195-
private void initPath(String path) {
196-
this.originalPath = path;
197-
replacePath(path);
198-
}
199-
200205
/**
201-
* Removes any path extension from the {@link HttpServletRequest#getRequestURI()
206+
* Remove any path extension from the {@link HttpServletRequest#getRequestURI()
202207
* requestURI}. This method must be invoked before any calls to {@link #path(String)}
203208
* or {@link #pathSegment(String...)}.
204209
* <pre>

spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java

+46-46
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@
1616

1717
package org.springframework.web.servlet.support;
1818

19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNull;
21+
1922
import org.junit.Before;
2023
import org.junit.Test;
21-
2224
import org.springframework.mock.web.test.MockHttpServletRequest;
2325
import org.springframework.web.context.request.RequestContextHolder;
2426
import org.springframework.web.context.request.ServletRequestAttributes;
2527
import org.springframework.web.util.UriComponents;
2628

27-
import static org.junit.Assert.*;
28-
2929
/**
3030
* Unit tests for
3131
* {@link org.springframework.web.servlet.support.ServletUriComponentsBuilder}.
@@ -47,59 +47,59 @@ public void setup() {
4747

4848
@Test
4949
public void fromRequest() {
50-
request.setRequestURI("/mvc-showcase/data/param");
51-
request.setQueryString("foo=123");
52-
String result = ServletUriComponentsBuilder.fromRequest(request).build().toUriString();
50+
this.request.setRequestURI("/mvc-showcase/data/param");
51+
this.request.setQueryString("foo=123");
52+
String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();
5353
assertEquals("http://localhost/mvc-showcase/data/param?foo=123", result);
5454
}
5555

5656
@Test
5757
public void fromRequestEncodedPath() {
58-
request.setRequestURI("/mvc-showcase/data/foo%20bar");
59-
String result = ServletUriComponentsBuilder.fromRequest(request).build().toUriString();
58+
this.request.setRequestURI("/mvc-showcase/data/foo%20bar");
59+
String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();
6060
assertEquals("http://localhost/mvc-showcase/data/foo%20bar", result);
6161
}
6262

6363
@Test
6464
public void fromRequestAtypicalHttpPort() {
65-
request.setServerPort(8080);
66-
String result = ServletUriComponentsBuilder.fromRequest(request).build().toUriString();
65+
this.request.setServerPort(8080);
66+
String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();
6767
assertEquals("http://localhost:8080", result);
6868
}
6969

7070
@Test
7171
public void fromRequestAtypicalHttpsPort() {
72-
request.setScheme("https");
73-
request.setServerPort(9043);
74-
String result = ServletUriComponentsBuilder.fromRequest(request).build().toUriString();
72+
this.request.setScheme("https");
73+
this.request.setServerPort(9043);
74+
String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();
7575
assertEquals("https://localhost:9043", result);
7676
}
7777

7878
@Test
7979
public void fromRequestUri() {
80-
request.setRequestURI("/mvc-showcase/data/param");
81-
request.setQueryString("foo=123");
82-
String result = ServletUriComponentsBuilder.fromRequestUri(request).build().toUriString();
80+
this.request.setRequestURI("/mvc-showcase/data/param");
81+
this.request.setQueryString("foo=123");
82+
String result = ServletUriComponentsBuilder.fromRequestUri(this.request).build().toUriString();
8383
assertEquals("http://localhost/mvc-showcase/data/param", result);
8484
}
8585

8686
@Test
8787
public void fromRequestWithForwardedHost() {
88-
request.addHeader("X-Forwarded-Host", "anotherHost");
89-
request.setRequestURI("/mvc-showcase/data/param");
90-
request.setQueryString("foo=123");
91-
String result = ServletUriComponentsBuilder.fromRequest(request).build().toUriString();
88+
this.request.addHeader("X-Forwarded-Host", "anotherHost");
89+
this.request.setRequestURI("/mvc-showcase/data/param");
90+
this.request.setQueryString("foo=123");
91+
String result = ServletUriComponentsBuilder.fromRequest(this.request).build().toUriString();
9292
assertEquals("http://anotherHost/mvc-showcase/data/param?foo=123", result);
9393
}
9494

9595
// SPR-10701
9696

9797
@Test
9898
public void fromRequestWithForwardedHostIncludingPort() {
99-
request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443");
100-
request.setRequestURI("/mvc-showcase/data/param");
101-
request.setQueryString("foo=123");
102-
UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build();
99+
this.request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443");
100+
this.request.setRequestURI("/mvc-showcase/data/param");
101+
this.request.setQueryString("foo=123");
102+
UriComponents result = ServletUriComponentsBuilder.fromRequest(this.request).build();
103103

104104
assertEquals("webtest.foo.bar.com", result.getHost());
105105
assertEquals(443, result.getPort());
@@ -132,7 +132,7 @@ public void fromRequestWithForwardedHostAndPort() {
132132
public void fromRequestWithForwardedHostWithDefaultPort() {
133133
this.request.setServerPort(10080);
134134
this.request.addHeader("X-Forwarded-Host", "example.org");
135-
UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build();
135+
UriComponents result = ServletUriComponentsBuilder.fromRequest(this.request).build();
136136

137137
assertEquals("example.org", result.getHost());
138138
assertEquals("should have used the default port of the forwarded request", -1, result.getPort());
@@ -143,7 +143,7 @@ public void fromRequestWithForwardedHostWithForwardedScheme() {
143143
this.request.setServerPort(10080);
144144
this.request.addHeader("X-Forwarded-Proto", "https");
145145
this.request.addHeader("X-Forwarded-Host", "example.org");
146-
UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build();
146+
UriComponents result = ServletUriComponentsBuilder.fromRequest(this.request).build();
147147

148148
assertEquals("example.org", result.getHost());
149149
assertEquals("should have derived scheme from header", "https", result.getScheme());
@@ -154,7 +154,7 @@ public void fromRequestWithForwardedHostWithForwardedScheme() {
154154
public void fromRequestWithForwardedPrefix() {
155155
this.request.setRequestURI("/bar");
156156
this.request.addHeader("X-Forwarded-Prefix", "/foo");
157-
UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build();
157+
UriComponents result = ServletUriComponentsBuilder.fromRequest(this.request).build();
158158

159159
assertEquals("http://localhost/foo/bar", result.toUriString());
160160
}
@@ -163,51 +163,51 @@ public void fromRequestWithForwardedPrefix() {
163163
public void fromRequestWithForwardedPrefixTrailingSlash() {
164164
this.request.setRequestURI("/bar");
165165
this.request.addHeader("X-Forwarded-Prefix", "/foo/");
166-
UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build();
166+
UriComponents result = ServletUriComponentsBuilder.fromRequest(this.request).build();
167167

168168
assertEquals("http://localhost/foo/bar", result.toUriString());
169169
}
170170

171171
@Test
172172
public void fromContextPath() {
173-
request.setRequestURI("/mvc-showcase/data/param");
174-
request.setQueryString("foo=123");
175-
String result = ServletUriComponentsBuilder.fromContextPath(request).build().toUriString();
173+
this.request.setRequestURI("/mvc-showcase/data/param");
174+
this.request.setQueryString("foo=123");
175+
String result = ServletUriComponentsBuilder.fromContextPath(this.request).build().toUriString();
176176
assertEquals("http://localhost/mvc-showcase", result);
177177
}
178178

179179
@Test
180180
public void fromContextPathWithForwardedPrefix() {
181-
request.addHeader("X-Forwarded-Prefix", "/prefix");
182-
request.setContextPath("/mvc-showcase");
183-
request.setRequestURI("/mvc-showcase/simple");
184-
String result = ServletUriComponentsBuilder.fromContextPath(request).build().toUriString();
181+
this.request.addHeader("X-Forwarded-Prefix", "/prefix");
182+
this.request.setContextPath("/mvc-showcase");
183+
this.request.setRequestURI("/mvc-showcase/simple");
184+
String result = ServletUriComponentsBuilder.fromContextPath(this.request).build().toUriString();
185185
assertEquals("http://localhost/prefix/mvc-showcase", result);
186186
}
187187

188188
@Test
189189
public void fromServletMapping() {
190-
request.setRequestURI("/mvc-showcase/app/simple");
191-
request.setServletPath("/app");
192-
request.setQueryString("foo=123");
193-
String result = ServletUriComponentsBuilder.fromServletMapping(request).build().toUriString();
190+
this.request.setRequestURI("/mvc-showcase/app/simple");
191+
this.request.setServletPath("/app");
192+
this.request.setQueryString("foo=123");
193+
String result = ServletUriComponentsBuilder.fromServletMapping(this.request).build().toUriString();
194194
assertEquals("http://localhost/mvc-showcase/app", result);
195195
}
196196

197197
@Test
198198
public void fromServletMappingWithForwardedPrefix() {
199-
request.addHeader("X-Forwarded-Prefix", "/prefix");
200-
request.setContextPath("/mvc-showcase");
201-
request.setServletPath("/app");
202-
request.setRequestURI("/mvc-showcase/app/simple");
203-
String result = ServletUriComponentsBuilder.fromServletMapping(request).build().toUriString();
199+
this.request.addHeader("X-Forwarded-Prefix", "/prefix");
200+
this.request.setContextPath("/mvc-showcase");
201+
this.request.setServletPath("/app");
202+
this.request.setRequestURI("/mvc-showcase/app/simple");
203+
String result = ServletUriComponentsBuilder.fromServletMapping(this.request).build().toUriString();
204204
assertEquals("http://localhost/prefix/mvc-showcase/app", result);
205205
}
206206

207207
@Test
208208
public void fromCurrentRequest() {
209-
request.setRequestURI("/mvc-showcase/data/param");
210-
request.setQueryString("foo=123");
209+
this.request.setRequestURI("/mvc-showcase/data/param");
210+
this.request.setQueryString("foo=123");
211211
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(this.request));
212212
try {
213213
String result = ServletUriComponentsBuilder.fromCurrentRequest().build().toUriString();

0 commit comments

Comments
 (0)