0

我有我的应用程序 url,我通过他们的电子邮件发送给最终用户。

现在该 url 包含“用户名”字段,该字段可以包含“@”字符。

例如发送给最终用户的链接:

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

现在,每当用户点击上面的链接时,它都会抛出以下异常:

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)

有没有办法处理这种情况,比如编码/解码 url?

4

3 回答 3

2

url 中不能有 @,因为它是保留字符(具体的 RFC 是RFC 3986)。

您可以使用URLEncoder 类将 url 编码为可接受的值

于 2012-04-30T09:47:11.957 回答
1

正如 MiniBill 已经回答的那样,这是行不通的,而且正如 Howard 所补充的那样,Tapestry 有自己的 URL 编码器。这意味着获取 Tapestry 可以读取格式的 URL 的最简单方法是让 Tapestry 创建它,然后将其传递给发送电子邮件的组件:

@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);
}
于 2012-05-02T11:38:39.100 回答
0

我能够通过将我的字符串编码为 Base64 并在 Tapestry Java 端解包来解决这个问题。我的字符串是 UTF-8 编码的字符。

我从这个答案修改了 Base64 编码器: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(/\=+$/, '');
}

(只是.replace最后加了,去掉=Tapestry 不喜欢的 padding )

在 Java 方面,解码轻而易举:(这个例子是来自 javascript 的 ajax 点击 - Base64 编码发生的地方)

@OnEvent(value = "clickAjax")
Object clickAjax(String parameter) {
    somePagePropetry = new String(java.util.Base64.getDecoder().decode(parameter));
    return this;
}
于 2017-04-15T16:00:35.727 回答