2012-04-30 2 views
0

J'ai l'URL de ma demande que j'envoie à l'utilisateur final dans ses emails.l'url de l'application contenant '@' lançant une exception

Maintenant que l'URL contient le champ 'nom d'utilisateur', qui peut contenir le caractère '@'.

Par exemple. lien qui a envoyé à l'utilisateur final:

http://localhost:8080/my-app/someaction/activateuser/[email protected]/somedata/ 

Maintenant, chaque fois que l'utilisateur clique sur lien ci-dessus, son lancement exception suivante:

java.lang.IllegalArgumentException 
    Input string '[email protected]' 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) 

Est-il possible de gérer ce scénario, comme l'encodage/décodage des urls ?

+0

Comment gérez-vous Nate l'URL? Il semble que vous fassiez le tour de la tapisserie normale pour générer une URL car, si je ne me trompe pas, Tapestry fait tout le codage pour vous. – joostschouten

Répondre

1

Comme MiniBill a déjà répondu, qui ne peuvent pas travailler, et comme Howard a ajouté, Tapestry a son propre encodeur pour les URL. Cela signifie que la meilleure façon pour vous d'obtenir une URL dans le format que Tapestry peut lire est d'avoir la tapisserie de créer, puis passer au composant qui envoie vos e-mails:

@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); 
} 
+0

@Hennings: fait de cette façon seulement ... merci pour la réponse .. – Nirmal

2

Vous ne pouvez pas avoir un @ dans l'URL, car il s'agit d'un caractère réservé (le RFC spécifique est RFC 3986).

Vous pouvez utiliser le URLEncoder class pour coder l'URL à une valeur acceptable

+0

Actuellement, Tapestry utilise son propre URLEncoder idiosyncractic; Cela est venu comme un moyen de normaliser le comportement à travers les conteneurs de servlets. C'est quelque chose qui doit être revisité. –

+0

ou juste dupliqué dans Tapestry.js en quelque sorte Howard? cela résoudrait beaucoup de problèmes s'il pouvait être répliqué sur le client ... – pstanton

0

j'ai pu résoudre le problème en encodant ma chaîne en Base64, et en décompressant sur le côté Java de Tapestry. Mes chaînes étaient des caractères encodés en UTF-8.

I modifié l'encodeur base64 de cette réponse: https://stackoverflow.com/a/40392850/5339857

function b64EncodeUnicode(str) { 
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { 
     return String.fromCharCode('0x' + p1); 
    })).replace(/\=+$/, ''); 
} 

(juste ajouté le .replace à la fin, pour enlever rembourrage = s que la tapisserie n'aime pas)

Et dans Java côté le décodage était un jeu d'enfant: (cet exemple est d'un clic ajax de javascript - où l'encodage Base64 se passe)

@OnEvent(value = "clickAjax") 
Object clickAjax(String parameter) { 
    somePagePropetry = new String(java.util.Base64.getDecoder().decode(parameter)); 
    return this; 
} 
Questions connexes