GithubHelp home page GithubHelp logo

Comments (9)

felixbarny avatar felixbarny commented on May 19, 2024 3

If someone faces the same issue, here is my workaround:

public final class LinkBuilderUtil {
    // ControllerLinkBuilder.linkTo has a problem: it double-URL-encodes characters!
    // e.g. ' ' (whitespace) is encoded to '%2525' instead of '%20'
    // TODO remove hack when https://github.com/spring-projects/spring-hateoas/issues/40 is resolved
    private static final Field uriComponentsField;

    static {
        try {
            uriComponentsField = LinkBuilderSupport.class.getDeclaredField("uriComponents");
            uriComponentsField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    private LinkBuilderUtil() {
    }

    public static String relativeLinkTo(Object invocationValue) {
        return UriComponentsBuilder.fromUriString(linkTo(invocationValue)).scheme(null).host(null).build().toUriString();
    }

    public static String linkTo(Object invocationValue) {
        try {
            final UriComponents uriComponents = (UriComponents) uriComponentsField.get(ControllerLinkBuilder.linkTo(invocationValue));
            return uriComponents.toString();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

from spring-hateoas.

felixbarny avatar felixbarny commented on May 19, 2024 1

I have a simmilar issue when using linkTo(methodOn(...)) if there are e.g. whitespaces in the parameters.
I think the problem sits in the toUri Method:

public URI toUri() {
    return uriComponents.encode().toUri();
}

imho it should be:

public URI toUri() {
    return uriComponents.toUri();
}

from spring-hateoas.

drewcox avatar drewcox commented on May 19, 2024

I too think I am seeing this behaviour, when trying to include a "{" in a path segment via a path parameter in the MVC Controller method mapping. The resulting encoding is "%257B" instead of the expected "%7B", due to double encoding.

I did a little picking through the source, and basically is seems the parameter is encoded once when going through the "expand" process for the URL template generated from controller method, then the entire path value is re-encoded when adding the link to the resource. Rough description...

from spring-hateoas.

meyertee avatar meyertee commented on May 19, 2024

Seems related to #96 which is marked as fixed, but it doesn't seem to be, I'm having the same issue using the LinkBuilder in various ways:

Link link = ControllerLinkBuilder.linkTo(ThingController.class).slash("my%20thing").withSelfRel();
link.getHref(); // returns "http://localhost:8080/things/my%2520thing"

Same happens using the EntityLinks:

Link link = entityLinks.linkToSingleResource(ThingResource.class, "my%20thing");

from spring-hateoas.

acorcoran-daon avatar acorcoran-daon commented on May 19, 2024

It appears that the problem is in UriTemplate:

public URI expand(Object... uriVariableValues) {
    UriComponents expandedComponents = this.uriComponents.expand(uriVariableValues);
    UriComponents encodedComponents = expandedComponents.encode();
    return encodedComponents.toUri();
}

This expandedComponents.encode() is causing any arguments for the URI template to be encoded. When the URI is encoded once again later ....

from spring-hateoas.

odrotbohm avatar odrotbohm commented on May 19, 2024

We've just pushed a removals for an unnecessary back-and-forth conversion in the course of the fix for #398. Does that maybe even fix that issue here?

from spring-hateoas.

pgpx avatar pgpx commented on May 19, 2024

This fixes my first test (thanks!), so the following passes:

Link l = linkToCurrentMapping().slash("first")
   .slash("sec%ond").slash("thi%rd").slash("fourth").withSelfRel();
assertEquals("http://localhost/first/sec%25ond/thi%25rd/fourth", l.getHref());

However, it doesn't encode any / characters at all - though maybe that is by design?

linkToCurrentMapping().slash("first")
    .slash("sec/ond").slash("third").withSelfRel();

I would like http://localhost/first/sec%2Fond/third but get http://localhost/first/sec/ond/third

from spring-hateoas.

gregturn avatar gregturn commented on May 19, 2024

.slash() basically appends "/" with the contents. However, "/" is still the token splitting thing, so .slash("sec/ond") is just like typing slash("sec").slash("ond").

To support this, we'd need to pre-encode the slash() command, which I'm not convinced on.

from spring-hateoas.

gregturn avatar gregturn commented on May 19, 2024

I think it's safe to say that if you NEED to encode a "/" and NOT have it split into two paths, you are responsible for that.

There is little way in framework code to detect this rare corner case.

from spring-hateoas.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.