Search code examples
javaurlurl-rewritingtapestry

application url containing '@' throwing an exception


I have my application url which I am sending the the end user on their emails.

Now that url contains the 'username' field, which can contains '@' character.

For e.g. link which sent to the end user :

http://localhost:8080/my-app/someaction/activateuser/abc@def.com/somedata/

Now whenever user clicks on above link, its throwing following exception :

java.lang.IllegalArgumentException
    Input string 'abc@def.com' is not valid; the character '@' at position 4 is not valid.
    at org.apache.tapestry5.internal.services.URLEncoderImpl.decode(URLEncoderImpl.java:144)
    at $URLEncoder_137022607d9.decode($URLEncoder_137022607d9.java)
    at org.apache.tapestry5.internal.services.ContextPathEncoderImpl.decodePath(ContextPathEncoderImpl.java:92)
    at $ContextPathEncoder_137022607cd.decodePath($ContextPathEncoder_137022607cd.java)
    at org.apache.tapestry5.internal.services.ComponentEventLinkEncoderImpl.checkIfPage(ComponentEventLinkEncoderImpl.java:328)
    at org.apache.tapestry5.internal.services.ComponentEventLinkEncoderImpl.decodePageRenderRequest(ComponentEventLinkEncoderImpl.java:307)
    at org.apache.tapestry5.internal.services.linktransform.LinkTransformerInterceptor.decodePageRenderRequest(LinkTransformerInterceptor.java:68)
    at $ComponentEventLinkEncoder_137022607c1.decodePageRenderRequest($ComponentEventLinkEncoder_137022607c1.java)
    at org.apache.tapestry5.internal.services.PageRenderDispatcher.dispatch(PageRenderDispatcher.java:41)
    at $Dispatcher_137022607c2.dispatch($Dispatcher_137022607c2.java)
    at $Dispatcher_137022607bd.dispatch($Dispatcher_137022607bd.java)
    at org.apache.tapestry5.services.TapestryModule$RequestHandlerTerminator.service(TapestryModule.java:321)
    at org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26)

Is there any way to handle such scenario, like encoding/decoding the urls ?


Solution

  • As MiniBill has already answered, that can't work, and as Howard has added, Tapestry has its own encoder for URLs. This means that the easiest way for you to get a URL in the format that Tapestry can read is to have Tapestry create it, and then pass it to the component that sends your emails:

    @Inject
    private LinkSource linkSource;
    
    @OnEvent(...)
    void sendActivationEmail() {
        final Link activationLink = this.createUserActivationLink(email, otherStuff);
        this.activationEmailSender.sendWithActivationLink(email, activationLink);
    }
    
    private Link createUserActivationLink(String email, String otherStuff) {
        return linkSource.createPageRenderLink(
           "someaction/activateuser", false, email, otherStuff);
    }