Add copyToUriComponentsBuilder method
After this change UriComponentsBuilder#uriComponents method no longer no longer copies from the given UriComponents but rather lets the UriComponents instance copy itself to the UriComponentsBuilder. This avoids the need for instanceof checks and also makes it possible to distinguish between path and path segments, which otherwise is internal knowledge of UriComponentsBuilder. Issue: SPR-12742
This commit is contained in:
@@ -417,6 +417,19 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
builder.scheme(getScheme());
|
||||||
|
builder.userInfo(getUserInfo());
|
||||||
|
builder.host(getHost());
|
||||||
|
builder.port(getPort());
|
||||||
|
builder.replacePath("");
|
||||||
|
this.path.copyToUriComponentsBuilder(builder);
|
||||||
|
builder.replaceQueryParams(getQueryParams());
|
||||||
|
builder.fragment(getFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
@@ -608,6 +621,8 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
void verify();
|
void verify();
|
||||||
|
|
||||||
PathComponent expand(UriTemplateVariables uriVariables);
|
PathComponent expand(UriTemplateVariables uriVariables);
|
||||||
|
|
||||||
|
void copyToUriComponentsBuilder(UriComponentsBuilder builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -651,6 +666,11 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
return new FullPathComponent(expandedPath);
|
return new FullPathComponent(expandedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
builder.path(getPath());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return (this == obj || (obj instanceof FullPathComponent &&
|
return (this == obj || (obj instanceof FullPathComponent &&
|
||||||
@@ -672,6 +692,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
private final List<String> pathSegments;
|
private final List<String> pathSegments;
|
||||||
|
|
||||||
public PathSegmentComponent(List<String> pathSegments) {
|
public PathSegmentComponent(List<String> pathSegments) {
|
||||||
|
Assert.notNull(pathSegments);
|
||||||
this.pathSegments = Collections.unmodifiableList(new ArrayList<String>(pathSegments));
|
this.pathSegments = Collections.unmodifiableList(new ArrayList<String>(pathSegments));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -723,6 +744,11 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
return new PathSegmentComponent(expandedPathSegments);
|
return new PathSegmentComponent(expandedPathSegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
builder.pathSegment(getPathSegments().toArray(new String[getPathSegments().size()]));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return (this == obj || (obj instanceof PathSegmentComponent &&
|
return (this == obj || (obj instanceof PathSegmentComponent &&
|
||||||
@@ -744,6 +770,7 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
private final List<PathComponent> pathComponents;
|
private final List<PathComponent> pathComponents;
|
||||||
|
|
||||||
public PathComponentComposite(List<PathComponent> pathComponents) {
|
public PathComponentComposite(List<PathComponent> pathComponents) {
|
||||||
|
Assert.notNull(pathComponents);
|
||||||
this.pathComponents = pathComponents;
|
this.pathComponents = pathComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -789,6 +816,13 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
}
|
}
|
||||||
return new PathComponentComposite(expandedComponents);
|
return new PathComponentComposite(expandedComponents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
for (PathComponent pathComponent : this.pathComponents) {
|
||||||
|
pathComponent.copyToUriComponentsBuilder(builder);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -816,6 +850,9 @@ final class HierarchicalUriComponents extends UriComponents {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return (this == obj);
|
return (this == obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -135,6 +135,13 @@ final class OpaqueUriComponents extends UriComponents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void copyToUriComponentsBuilder(UriComponentsBuilder builder) {
|
||||||
|
builder.scheme(getScheme());
|
||||||
|
builder.schemeSpecificPart(getSchemeSpecificPart());
|
||||||
|
builder.fragment(getFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -203,6 +203,12 @@ public abstract class UriComponents implements Serializable {
|
|||||||
return toUriString();
|
return toUriString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set all components of the given UriComponentsBuilder.
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
protected abstract void copyToUriComponentsBuilder(UriComponentsBuilder builder);
|
||||||
|
|
||||||
|
|
||||||
// static expansion helpers
|
// static expansion helpers
|
||||||
|
|
||||||
|
|||||||
@@ -447,40 +447,7 @@ public class UriComponentsBuilder implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
public UriComponentsBuilder uriComponents(UriComponents uriComponents) {
|
public UriComponentsBuilder uriComponents(UriComponents uriComponents) {
|
||||||
Assert.notNull(uriComponents, "'uriComponents' must not be null");
|
Assert.notNull(uriComponents, "'uriComponents' must not be null");
|
||||||
this.scheme = uriComponents.getScheme();
|
uriComponents.copyToUriComponentsBuilder(this);
|
||||||
if (uriComponents instanceof OpaqueUriComponents) {
|
|
||||||
this.ssp = uriComponents.getSchemeSpecificPart();
|
|
||||||
resetHierarchicalComponents();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (uriComponents.getUserInfo() != null) {
|
|
||||||
this.userInfo = uriComponents.getUserInfo();
|
|
||||||
}
|
|
||||||
if (uriComponents.getHost() != null) {
|
|
||||||
this.host = uriComponents.getHost();
|
|
||||||
}
|
|
||||||
if (uriComponents.getPort() != -1) {
|
|
||||||
this.port = String.valueOf(uriComponents.getPort());
|
|
||||||
}
|
|
||||||
if (StringUtils.hasLength(uriComponents.getPath())) {
|
|
||||||
List<String> segments = uriComponents.getPathSegments();
|
|
||||||
if (segments.isEmpty()) {
|
|
||||||
// Perhaps "/"
|
|
||||||
this.pathBuilder.addPath(uriComponents.getPath());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.pathBuilder.addPathSegments(segments.toArray(new String[segments.size()]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!uriComponents.getQueryParams().isEmpty()) {
|
|
||||||
this.queryParams.clear();
|
|
||||||
this.queryParams.putAll(uriComponents.getQueryParams());
|
|
||||||
}
|
|
||||||
resetSchemeSpecificPart();
|
|
||||||
}
|
|
||||||
if (uriComponents.getFragment() != null) {
|
|
||||||
this.fragment = uriComponents.getFragment();
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -679,6 +646,18 @@ public class UriComponentsBuilder implements Cloneable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the query parameter values overriding all existing query values.
|
||||||
|
* @param params the query parameter name
|
||||||
|
* @return this UriComponentsBuilder
|
||||||
|
*/
|
||||||
|
public UriComponentsBuilder replaceQueryParams(MultiValueMap<String, String> params) {
|
||||||
|
Assert.notNull(params, "'params' must not be null");
|
||||||
|
this.queryParams.clear();
|
||||||
|
this.queryParams.putAll(params);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the URI fragment. The given fragment may contain URI template variables,
|
* Set the URI fragment. The given fragment may contain URI template variables,
|
||||||
* and may also be {@code null} to clear the fragment of this builder.
|
* and may also be {@code null} to clear the fragment of this builder.
|
||||||
|
|||||||
@@ -436,6 +436,15 @@ public class UriComponentsBuilderTests {
|
|||||||
assertEquals("https://a.example.org/mvc-showcase", result.toString());
|
assertEquals("https://a.example.org/mvc-showcase", result.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SPR-12742
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromHttpRequestWithTrailingSlash() throws Exception {
|
||||||
|
UriComponents before = UriComponentsBuilder.fromPath("/foo/").build();
|
||||||
|
UriComponents after = UriComponentsBuilder.newInstance().uriComponents(before).build();
|
||||||
|
assertEquals("/foo/", after.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void path() throws URISyntaxException {
|
public void path() throws URISyntaxException {
|
||||||
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar");
|
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -22,6 +22,7 @@ import java.io.ObjectInputStream;
|
|||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -132,6 +133,16 @@ public class UriComponentsTests {
|
|||||||
assertThat(uriComponents.toString(), equalTo(readObject.toString()));
|
assertThat(uriComponents.toString(), equalTo(readObject.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copyToUriComponentsBuilder() {
|
||||||
|
UriComponents source = UriComponentsBuilder.fromPath("/foo/bar").pathSegment("ba/z").build();
|
||||||
|
UriComponentsBuilder targetBuilder = UriComponentsBuilder.newInstance();
|
||||||
|
source.copyToUriComponentsBuilder(targetBuilder);
|
||||||
|
UriComponents result = targetBuilder.build().encode();
|
||||||
|
assertEquals("/foo/bar/ba%2Fz", result.getPath());
|
||||||
|
assertEquals(Arrays.asList("foo", "bar", "ba%2Fz"), result.getPathSegments());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void equalsHierarchicalUriComponents() throws Exception {
|
public void equalsHierarchicalUriComponents() throws Exception {
|
||||||
UriComponents uriComponents1 = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo}").query("bar={baz}").build();
|
UriComponents uriComponents1 = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo}").query("bar={baz}").build();
|
||||||
|
|||||||
Reference in New Issue
Block a user