Support port URI template variables
This commit makes it possible to specify port with an URI template variable. For example : RestTemplate restTemplate = new RestTemplate(); restTemplate.getForObject("http://localhost:{port}/resource", String.class, 8080); Issue: SPR-12123
This commit is contained in:
parent
0b02551e2f
commit
8fbd310b07
|
@ -52,7 +52,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
|
||||
private final String host;
|
||||
|
||||
private final int port;
|
||||
private final String port;
|
||||
|
||||
private final PathComponent path;
|
||||
|
||||
|
@ -73,7 +73,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
* @param encoded whether the components are already encoded
|
||||
* @param verify whether the components need to be checked for illegal characters
|
||||
*/
|
||||
HierarchicalUriComponents(String scheme, String userInfo, String host, int port, PathComponent path,
|
||||
HierarchicalUriComponents(String scheme, String userInfo, String host, String port, PathComponent path,
|
||||
MultiValueMap<String, String> queryParams, String fragment, boolean encoded, boolean verify) {
|
||||
|
||||
super(scheme, fragment);
|
||||
|
@ -109,7 +109,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return this.port;
|
||||
return Integer.parseInt(this.port);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -308,6 +308,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
String expandedScheme = expandUriComponent(getScheme(), uriVariables);
|
||||
String expandedUserInfo = expandUriComponent(this.userInfo, uriVariables);
|
||||
String expandedHost = expandUriComponent(this.host, uriVariables);
|
||||
String expandedPort = expandUriComponent(this.port, uriVariables);
|
||||
PathComponent expandedPath = this.path.expand(uriVariables);
|
||||
MultiValueMap<String, String> expandedQueryParams =
|
||||
new LinkedMultiValueMap<String, String>(this.queryParams.size());
|
||||
|
@ -321,7 +322,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
expandedQueryParams.put(expandedName, expandedValues);
|
||||
}
|
||||
String expandedFragment = expandUriComponent(this.getFragment(), uriVariables);
|
||||
return new HierarchicalUriComponents(expandedScheme, expandedUserInfo, expandedHost, this.port, expandedPath,
|
||||
return new HierarchicalUriComponents(expandedScheme, expandedUserInfo, expandedHost, expandedPort, expandedPath,
|
||||
expandedQueryParams, expandedFragment, false, false);
|
||||
}
|
||||
|
||||
|
@ -359,7 +360,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
if (this.host != null) {
|
||||
uriBuilder.append(host);
|
||||
}
|
||||
if (this.port != -1) {
|
||||
if (!"-1".equals(this.port)) {
|
||||
uriBuilder.append(':');
|
||||
uriBuilder.append(port);
|
||||
}
|
||||
|
@ -432,7 +433,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||
int result = ObjectUtils.nullSafeHashCode(getScheme());
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.userInfo);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.host);
|
||||
result = 31 * result + this.port;
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(this.port);
|
||||
result = 31 * result + this.path.hashCode();
|
||||
result = 31 * result + this.queryParams.hashCode();
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(getFragment());
|
||||
|
|
|
@ -70,7 +70,7 @@ public class UriComponentsBuilder {
|
|||
|
||||
private static final String HOST_PATTERN = "(" + HOST_IPV6_PATTERN + "|" + HOST_IPV4_PATTERN + ")";
|
||||
|
||||
private static final String PORT_PATTERN = "(\\d*)";
|
||||
private static final String PORT_PATTERN = "(\\d*(?:\\{[^/]+?\\})?)";
|
||||
|
||||
private static final String PATH_PATTERN = "([^?#]*)";
|
||||
|
||||
|
@ -96,7 +96,7 @@ public class UriComponentsBuilder {
|
|||
|
||||
private String host;
|
||||
|
||||
private int port = -1;
|
||||
private String port = "-1";
|
||||
|
||||
private CompositePathComponentBuilder pathBuilder = new CompositePathComponentBuilder();
|
||||
|
||||
|
@ -192,7 +192,7 @@ public class UriComponentsBuilder {
|
|||
builder.userInfo(userInfo);
|
||||
builder.host(host);
|
||||
if (StringUtils.hasLength(port)) {
|
||||
builder.port(Integer.parseInt(port));
|
||||
builder.port(port);
|
||||
}
|
||||
builder.path(path);
|
||||
builder.query(query);
|
||||
|
@ -237,7 +237,7 @@ public class UriComponentsBuilder {
|
|||
builder.host(host);
|
||||
String port = m.group(7);
|
||||
if (StringUtils.hasLength(port)) {
|
||||
builder.port(Integer.parseInt(port));
|
||||
builder.port(port);
|
||||
}
|
||||
builder.path(m.group(8));
|
||||
builder.query(m.group(10));
|
||||
|
@ -272,7 +272,7 @@ public class UriComponentsBuilder {
|
|||
return new OpaqueUriComponents(this.scheme, this.ssp, this.fragment);
|
||||
}
|
||||
else {
|
||||
return new HierarchicalUriComponents(this.scheme, this.userInfo, this.host, this.port,
|
||||
return new HierarchicalUriComponents(this.scheme, this.userInfo, this.host, String.valueOf(this.port),
|
||||
this.pathBuilder.build(), this.queryParams, this.fragment, encoded, true);
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ public class UriComponentsBuilder {
|
|||
this.host = uri.getHost();
|
||||
}
|
||||
if (uri.getPort() != -1) {
|
||||
this.port = uri.getPort();
|
||||
this.port = String.valueOf(uri.getPort());
|
||||
}
|
||||
if (StringUtils.hasLength(uri.getRawPath())) {
|
||||
this.pathBuilder = new CompositePathComponentBuilder(uri.getRawPath());
|
||||
|
@ -353,7 +353,7 @@ public class UriComponentsBuilder {
|
|||
private void resetHierarchicalComponents() {
|
||||
this.userInfo = null;
|
||||
this.host = null;
|
||||
this.port = -1;
|
||||
this.port = "-1";
|
||||
this.pathBuilder = new CompositePathComponentBuilder();
|
||||
this.queryParams.clear();
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ public class UriComponentsBuilder {
|
|||
this.host = uriComponents.getHost();
|
||||
}
|
||||
if (uriComponents.getPort() != -1) {
|
||||
this.port = uriComponents.getPort();
|
||||
this.port = String.valueOf(uriComponents.getPort());
|
||||
}
|
||||
if (StringUtils.hasLength(uriComponents.getPath())) {
|
||||
List<String> segments = uriComponents.getPathSegments();
|
||||
|
@ -462,6 +462,18 @@ public class UriComponentsBuilder {
|
|||
*/
|
||||
public UriComponentsBuilder port(int port) {
|
||||
Assert.isTrue(port >= -1, "'port' must not be < -1");
|
||||
this.port = String.valueOf(port);
|
||||
resetSchemeSpecificPart();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URI port. Passing {@code "-1"} will clear the port of this builder.
|
||||
* The given port may contain URI template variables.
|
||||
* @param port the URI port
|
||||
* @return this UriComponentsBuilder
|
||||
*/
|
||||
public UriComponentsBuilder port(String port) {
|
||||
this.port = port;
|
||||
resetSchemeSpecificPart();
|
||||
return this;
|
||||
|
|
|
@ -54,6 +54,7 @@ public class AbstractJettyServerTestCase {
|
|||
|
||||
protected static String helloWorld = "H\u00e9llo W\u00f6rld";
|
||||
|
||||
protected static int port;
|
||||
protected static String baseUrl;
|
||||
|
||||
protected static MediaType textContentType;
|
||||
|
@ -63,7 +64,7 @@ public class AbstractJettyServerTestCase {
|
|||
|
||||
@BeforeClass
|
||||
public static void startJettyServer() throws Exception {
|
||||
int port = SocketUtils.findAvailableTcpPort();
|
||||
port = SocketUtils.findAvailableTcpPort();
|
||||
jettyServer = new Server(port);
|
||||
baseUrl = "http://localhost:" + port;
|
||||
ServletContextHandler handler = new ServletContextHandler();
|
||||
|
|
|
@ -229,6 +229,14 @@ public class RestTemplateIntegrationTests extends AbstractJettyServerTestCase {
|
|||
assertTrue(s.contains("\"without\":\"without\""));
|
||||
}
|
||||
|
||||
// SPR-12123
|
||||
|
||||
@Test
|
||||
public void serverPort() {
|
||||
String s = template.getForObject("http://localhost:{port}/get", String.class, port);
|
||||
assertEquals("Invalid content", helloWorld, s);
|
||||
}
|
||||
|
||||
public interface MyJacksonView1 {};
|
||||
public interface MyJacksonView2 {};
|
||||
|
||||
|
|
|
@ -80,6 +80,28 @@ public class UriComponentsTests {
|
|||
assertEquals("http://example.com/1 2 3 4", uriComponents.toUriString());
|
||||
}
|
||||
|
||||
// SPR-12123
|
||||
|
||||
@Test
|
||||
public void port() {
|
||||
UriComponents uriComponents1 = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com:8080/bar").build();
|
||||
UriComponents uriComponents2 = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/bar").port(8080).build();
|
||||
UriComponents uriComponents3 = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/bar").port("{port}").build().expand(8080);
|
||||
UriComponents uriComponents4 = UriComponentsBuilder.fromUriString(
|
||||
"http://example.com/bar").port("808{digit}").build().expand(0);
|
||||
assertEquals(8080, uriComponents1.getPort());
|
||||
assertEquals("http://example.com:8080/bar", uriComponents1.toUriString());
|
||||
assertEquals(8080, uriComponents2.getPort());
|
||||
assertEquals("http://example.com:8080/bar", uriComponents2.toUriString());
|
||||
assertEquals(8080, uriComponents3.getPort());
|
||||
assertEquals("http://example.com:8080/bar", uriComponents3.toUriString());
|
||||
assertEquals(8080, uriComponents4.getPort());
|
||||
assertEquals("http://example.com:8080/bar", uriComponents4.toUriString());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void expandEncoded() {
|
||||
UriComponentsBuilder.fromPath("/{foo}").build().encode().expand("bar");
|
||||
|
|
Loading…
Reference in New Issue