如何(正确)在Java中创建mailto URL(URI)?

2022-09-03 02:16:19

鉴于:

String email1 = "simple@example.org";

// legal email address according to wikipedia [1]
String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org";

创建 mailto: URI(以 String 对象的形式)的最佳/正确方法是什么?

我试过了:

String uri = new URI("mailto", the_email_address, null).toString();

这是我得到的最接近的,但它没有在电子邮件地址的本地部分编码问号(?),但根据RFC 6068,它应该编码。它在RFC中的示例上也失败,例如“not@me”@example.orgunlikely?address@example.com

[1] Valid_email_addresses示例

PS:有一些有用的信息 应该在加编码 在 mailto: 超链接?


我将其作为解决方案:

import org.apache.http.client.utils.URIBuilder;
// from Apache HttpClient
// maven group: org.apache.httpcomponents artifact: httpclient

String emailURL = new URIBuilder().setScheme("mailto").setPath(the_email_address).toString();

答案 1

您必须手动对 和 进行百分比编码/转义。?&

String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org";
String uri2 = (new URI("mailto", email2, null)).toString().replace("?", "%3F").replace("&", "%26");

因此,在 URI 中似乎没有正确转义 和 符号。在 URI 中忽略 后面的任何内容,因为该符号是为 URL 中的“查询字符串”保留的。请参考此处?&?

根据这个和参考文件,我们也需要逃脱。出于某种原因,Java并没有为我们做到这一点。事实上,RFC 6068甚至指出:&

可以出现在 中的字符数必须经过百分比编码。根据 [STD66] 以及 “%”(因为它用于百分比编码)以及 gen-delims 中除 “@” 和 “:” (即 “/”,“?”、“#”、“[” 和 “]”)之外,这些字符不能出现在 URI 中。在子行中的字符中,至少以下字符也必须进行百分比编码:“&”、“;”和“=”。

修复它的方法(有点黑客,但它有效)是使用符号的2位数字ASCII十六进制值手动转义这些字符。请参考此内容%

我通过将生成的字符串粘贴到Chrome中进行了测试,它正确地打开了我的默认电子邮件,其中包含一封电子邮件

"()<>[]:,; @\"!#$%&'*+-/=?^_`{}| ~.a"@example.org

更多研究

因此,Java的URI类似乎使用RFC 2396,其中指出:

如果 URI 组件的数据与保留目的冲突,则必须在形成 URI 之前对冲突的数据进行转义。

 reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
            "$" | ","

上面的“保留”语法类是指在 URI 中允许的字符,但在通用 URI 语法的特定组件中可能不允许的字符;


答案 2

您将必须使用Apache Commons URI构建器

该值应为未转义,并且可能包含非 ASCII 字符。

你不能直接使用java uri类 Java URI doc
所有标点符号字符都是保留的,字符串中的那些“?/[]@”保留的

Java的URI类使用RFC 2396,该声明:如果URI组件的数据与保留目的冲突,则必须在形成URI之前对冲突的数据进行转义。

 reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
            "$" | ","

您可以使用 对user_name进行编码,然后使用编码的用户名创建 URI,也可以
手动对 ?和 &.java.net.URLEncoderString uri = new URI("mailto", the_email_address, null).toString();

String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org";
String uri2 = (new URI("mailto", email2, null)).toString().replace("?", "%3F").replace("&", "%26");

在JavaScript中,您可以使用该函数。PHP有这个功能,ASP有这个功能。encodeURI()rawurlencode()Server.URLEncode()



推荐