Given:
String email1 = "[email protected]";
// legal email address according to wikipedia [1]
String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org";
What is the best/correct way to create a mailto: URI (in the form of a String object)?
I tried:
String uri = new URI("mailto", the_email_address, null).toString();
This is the closest I got, but it does not encode the question-mark (?) in the local part of the email address, but according to RFC 6068 it should. It also fails on examples in the RFC, like "not@me"@example.org or [email protected].
[1] Valid_email_addresses examples
PS: There is some useful information in Should plus be encoded in mailto: hyperlinks?
I settled for this as a solution:
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();
A mailto link is a Uniform Resource Identifier (URI) scheme for email addresses. It is a type of HTML or URL link that activates the default mail client (Gmail, Outlook etc.)
A URI is a uniform resource identifier while a URL is a uniform resource locator. Hence every URL is a URI, abstractly speaking, but not every URI is a URL. This is because there is another subcategory of URIs, uniform resource names (URNs), which name resources but do not specify how to locate them.
An opaque URI has a scheme, a scheme-specific part, and possibly a fragment, but has no other components. A hierarchical URI always has a path (though it may be empty) and a scheme-specific-part (which at least contains the path), and may have any of the other components.
You have to manually percent encode/escape the ?
and &
.
String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org";
String uri2 = (new URI("mailto", email2, null)).toString().replace("?", "%3F").replace("&", "%26");
So it seems that the ?
and &
symbols are not being correctly escaped in the URI. Anything after the ?
is ignored in the URI because that symbol is reserved for "query strings" in URLs. Reference here.
According to this and the reference documents, we need to escape &
as well. For some reason, Java is not doing that for us. In fact, RFC 6068 even states:
A number of characters that can appear in MUST be percent-encoded. These are the characters that cannot appear in a URI according to [STD66] as well as "%" (because it is used for percent-encoding) and all the characters in gen-delims except "@" and ":" (i.e., "/", "?", "#", "[", and "]"). Of the characters in sub-delims, at least the following also have to be percent- encoded: "&", ";", and "=".
The way to fix it (somewhat of a hack, but it works) is to manually escape these characters using a %
followed by 2 digit ASCII hex value for symbol. Reference this.
I tested by pasting the resulting string into Chrome and it correctly opened up my default email with an email to
"()<>[]:,; @\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
More Research
So it seems that Java's URI class uses RFC 2396, which states:
If the data for a URI component would conflict with the reserved purpose, then the conflicting data must be escaped before forming the URI.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
The "reserved" syntax class above refers to those characters that are allowed within a URI, but which may not be allowed within a particular component of the generic URI syntax;
You will have to use Apache Commons URI builder
The value is expected to be unescaped and may contain non ASCII characters.
You can not directly use java uri class Java URI doc says
All punctuation characters are Reserved together with those in the string "?/[]@" are reserved.
Java's URI class uses RFC 2396, which states:If the data for a URI component would conflict with the reserved purpose, then the conflicting data must be escaped before forming the URI.
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
You can use
java.net.URLEncoder
to encode the user_name and then use encoded username to create the URIString uri = new URI("mailto", the_email_address, null).toString();
or
You can manually percent encode/escape the ? and &.String email2 = "\"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org"; String uri2 = (new URI("mailto", email2, null)).toString().replace("?", "%3F").replace("&", "%26");
In JavaScript you can use the
encodeURI()
function. PHP has therawurlencode()
function, and ASP has theServer.URLEncode()
function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With