包含'@'的应用程序URL抛出异常

时间:2012-04-30 09:14:20

标签: java url url-rewriting tapestry

我有我的应用程序网址,我将最终用户发送给他们的电子邮件。

现在,url包含'username'字段,该字段可以包含'@'字符。

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

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)

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

3 个答案:

答案 0 :(得分:2)

您在网址中不能包含@,因为它是保留字符(特定RFC为RFC 3986)。

您可以使用URLEncoder class将网址编码为可接受的值

答案 1 :(得分:1)

正如MiniBill已经回答的那样,这是行不通的,正如霍华德所说,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);
}

答案 2 :(得分:0)

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

我从这个答案修改了Base64编码器:https://stackoverflow.com/a/40392850/5339857

Prelude> Control.Applicative.liftA2 (+) [0,10..30] [0..3]
[0,1,2,3,10,11,12,13,20,21,22,23,30,31,32,33]

(最后添加了using System; namespace _50_Million { class Program { static void Main(string[] args) { Console.Write("Enter Number "); string number = Console.ReadLine(); Console.Write("What to divide by "); string divide = Console.ReadLine(); Console.Write("How many times "); string d = Console.ReadLine(); decimal previousNumber = Convert.ToDecimal(number); decimal times = Convert.ToDecimal(d); decimal divideDecimal = Convert.ToDecimal(divide); var watch = System.Diagnostics.Stopwatch.StartNew(); decimal newNumber = 0; for (int i = 0; i < times; i++) { newNumber = previousNumber / divideDecimal; previousNumber = newNumber; } watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; Console.WriteLine("It has taken " + elapsedMs + " millisecounds to divide " + number + " by " + divide + ", " + d + " times."); Console.WriteLine("The Answer is " + newNumber); Console.ReadLine(); } } } ,以删除Tapestry不喜欢的填充function b64EncodeUnicode(str) { return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) { return String.fromCharCode('0x' + p1); })).replace(/\=+$/, ''); }

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

.replace