question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using UriComponentsBuilder.cloneBuilder does not copy uriVariables

See original GitHub issue

According to the docs, when you do UriComponentsBuilder.cloneBuilder (v5.2.5.RELEASE) it should create a deep clone: https://github.com/spring-projects/spring-framework/blob/c08e31b7d613bf91cbe2beac2dad66714403faee/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java#L146-L162

However, if your builder has pathSegments the uriVariables will not be preserved. Imagine the following scenario - you have a base builder which you are going to receive and you need to append path(s) to it. Here is an oversimplified example:

public UriComponentsBuilder getStorageBuilder(int userId, String storageName) {
    HashMap<String, Object> uriVariables = new HashMap<>();
    uriVariables.put("userId", userId);
    uriVariables.put("storageId", storageName);

    UriComponentsBuilder baseBuilder = ServletUriComponentsBuilder.fromCurrentRequest();
    baseBuilder.replacePath("/storages");
    baseBuilder.pathSegment("{userId}");
    baseBuilder.pathSegment("{storageName}");
    baseBuilder.uriVariables(uriVariables);

    return baseBuilder;
}
....

// Receive a configured `builder` (something else calls `getStorageBuilder` before this method and it's passed as an argument here)
public UriComponentsBuilder getStorageDirectoryListing(UriComponentsBuilder baseBuilder, String path) {
    // http://localhost/storages/%7BuserId%7D/%7BstorageName%7D/some/path
    return baseBuilder.cloneBuilder().path(path).toUriString();
}

In this case the cloned builder will not have the uriVariables copied. Furthermore, there is no getter method for the uriVariables so you can’t manually copy them. A quick’n’dirty workaround to this is would be:

String fileUrl = UriComponentsBuilder.fromUriString(baseBuilder.toUriString())
                                     .path("/some/path").build().toUriString();

Unfortunately this removes the ability to change anything in the pathSegments. Is there anything I’m missing here for uriVariables to be excluded when cloning or is this simply missing at the moment?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
jhoellercommented, Mar 25, 2020

It seems that #21565 introduced that uriVariables field in 5.0.8 but didn’t include it in the cloning step. Let’s backport this fix to 5.1.x and 5.0.x as well in order to close that gap in all affected branches.

1reaction
rstoyanchevcommented, Mar 25, 2020

It looks like it’s simply missing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

UriComponentsBuilder (Spring Framework 6.0.2 API)
Create a URI components builder from the given HTTP URL String. ... Set the query parameter values replacing existing values, or if no...
Read more >
Guide to UriComponentsBuilder in Spring - Baeldung
A quick and practical guide to using UriComponentsBuilder in Spring. ... The problem is, of course, when things fall apart in production ...
Read more >
org.springframework.web.util.UriComponentsBuilder.java ...
Here is the source code for org.springframework.web.util. ... This * method replaces ";" with "%3B" in URI variables but not in the URI...
Read more >
org.springframework.web.util.UriComponentsBuilder.encode ...
<p>In comparison to {@link UriComponents#encode()}, this method has the * same ... This * method replaces ";" with "%3B" in URI variables but...
Read more >
ServletUriComponentsBuilder (Spring Framework 5.2.1.RELEASE ...
public class ServletUriComponentsBuilder extends UriComponentsBuilder ... Note: As of 5.1, methods in this class do not extract "Forwarded" and ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found