How can I encode URL query parameter values? I need to replace spaces with %20, accents, non-ASCII characters etc.
I tried to use URLEncoder but it also encodes / character and if I give a string encoded with URLEncoder to the URL constructor I get a MalformedURLException (no protocol).
URLEncoder has a very misleading name. It is according to the Javadocs used encode form parameters using MIME type application/x-www-form-urlencoded.
With this said it can be used to encode e.g., query parameters. For instance if a parameter looks like &/?# its encoded equivalent can be used as:
String url = "http://host.com/?key=" + URLEncoder.encode("&/?#");
Unless you have those special needs the URL javadocs suggests using new URI(..).toURL which performs URI encoding according to RFC2396.
The recommended way to manage the encoding and decoding of URLs is to use URI
The following sample
new URI("http", "host.com", "/path/", "key=| ?/#ä", "fragment").toURL();
produces the result http://host.com/path/?key=%7C%20?/%23ä#fragment. Note how characters such as ?&/ are not encoded.
For further information, see the posts HTTP URL Address Encoding in Java or how to encode URL to avoid special characters in java.
EDIT
Since your input is a string URL, using one of the parameterized constructor of URI will not help you. Neither can you use new URI(strUrl) directly since it doesn't quote URL parameters.
So at this stage we must use a trick to get what you want:
public URL parseUrl(String s) throws Exception {
URL u = new URL(s);
return new URI(
u.getProtocol(),
u.getAuthority(),
u.getPath(),
u.getQuery(),
u.getRef()).
toURL();
}
Before you can use this routine you have to sanitize your string to ensure it represents an absolute URL. I see two approaches to this:
Guessing. Prepend http:// to the string unless it's already present.
Construct the URI from a context using new URL(URL context, String spec)
So what you're saying is that you want to encode part of your URL but not the whole thing. Sounds to me like you'll have to break it up into parts, pass the ones that you want encoded through the encoder, and re-assemble it to get your whole URL.
Related
{URL}/text=Congratulations%21+You+are+eligible+for+.%0A
%0A = New line encoded character
I am passing encoded new line syntax in parameter. But the problem is that when I am building the above URL then its again encoded the % as %25
so above URL become {URL}/text=Congratulations%21+You+are+eligible+for+.%250A
I am not able to understand why URLBuilder encode already encoded character.
Used below code for building URLBuilder
URI url = new URIBuilder("URL").build();
If you don't need url encoding why do you use URIBuilder at all? You could simply create a new URI.
You need #buildFromEncoded if you want to feed in pre-encoded strings.
I am trying to construct a URL in Java, with the query parameters encoded.The encoder should escape the character '+'. All the methods that I've come across encode it. Is there any way I can accomplish this or do I need to write a custom encoder?
Thanks!
Try "UriComponentsBuilder" if your using Spring.This package also contains other options that may fullfill your requirement.
UriComponentsBuilder.fromPath("URL String");
If your not using Spring can use "UrlValidator" given by "apache.commons"
String[] schemes = {"http","https"}; // DEFAULT schemes = "http", "https", "ftp"
UrlValidator urlValidator = new UrlValidator(schemes);
if (urlValidator.isValid("urlString")) {
System.out.println("URL is valid");
} else {
System.out.println("URL is invalid");
}
The URI class should be able to do this for you. Specifically, use
URI(String scheme, String userInfo, String host,
int port, String path, String query, String fragment)
or
URI(String scheme, String authority, String path, String query,
String fragment)
to create the URI object, where the components that you provided are not encoded. Then use URI.toString() or URI.toASCIIString() to produce the properly encoded URL.
The encoder should escape the character '+'. All the methods that I've come across encode it.
Encoding the '+' as %2B% is the correct behavior. The URL / URI specifications do not support escaping. Any unencoded '+' in a URL will decode as a space character, no matter how you try to escape it. That's what the spec says.
I have a URL "ssh://root:zstackqwe:!###172.16.36.184" which contains "#" and ":" in the password part. I use java.net.URI to wrap the string like:
URI u1 = new URI("ssh://root:zstackqwe:!###172.16.36.184/");
System.out.println(u1.getAuthority());
System.out.println(u1.getHost());
the output is:
root:zstackqwe:!#
null
The authority part is correct while the host part returns null. How should correctly handle those special chars?
UPDATE:
The string "ssh://root:zstackqwe:!###172.16.36.184" is a raw string without any encoding, passed from the API to my application. I am unable to use constructors other than UIR(string). So I am looking for a way to handle the raw string making it work with jave.net.URI.
If it's a URI use percent encoding.
URI u1 = new URI("ssh://root:zstackqwe%3a!%40%23#172.16.36.184/");
So that string comes from someone else:
It's mal-formed. Get them to submit a correctly formed URL instead.
I have problems with the character +(and maybe others) at the URIBuilder is suppose to get a decoded url but when I extract the query the + is replaced
String decodedUrl = "www.foo.com?sign=AZrhQaTRSiys5GZtlwZ+H3qUyIY=&more=boo";
URIBuilder builder = new URIBuilder(decodedUrl);
List<NameValuePair> params = builder.getQueryParams();
String sign = params.get(0).getValue();
the value of sing is AZrhQaTRSiys5GZtlwZ H3qUyIY= with a space instead +. How can I extract the correct value?
other way is:
URI uri = new URI(decodedUrl);
String query = uri.getQuery();
the value of query is sign=AZrhQaTRSiys5GZtlwZ+H3qUyIY=&more=boo in this case is correct, but I have to strip it. Is there another way to do that?
Use it differently:
String decodedUrl = "www.foo.com";
URIBuilder builder = new URIBuilder(decodedUrl);
builder.addParameter("sign", "AZrhQaTRSiys5GZtlwZ+H3qUyIY=");
builder.addParameter("more", "boo");
List<NameValuePair> params = builder.getQueryParams();
String sign = params.get(0).getValue();
addParameter method is responsible for adding parameters as to the builder. The constructor of the builder should include the base URL only.
If this URL is given to you as is, then the + is already decoded and stands for the space character. If you are the one who generates this URL, you probably skipped the URL encoding step (which can be done using the code snipped above).
Read a bit about URL encoding: http://en.wikipedia.org/wiki/Query_string#URL_encoding
That is because if you send space as parameter in url it is encoded as +. This happens because there are some rules which characters are valid in URL. See URL RFC.
It is necessary to encode any characters disallowed in a URL, including spaces and other binary data not in the allowed character set, using the standard convention of the "%" character followed by two hexadecimal digits.
If you want to have + as symbol in url you need to encode it into %2B. For example 2+2 is encoded as 2%2B2 and i am as i+am. So in your case I believe you have to correct result as AZrhQaTRSiys5GZtlwZ+H3qUyIY decodes into AZrhQaTRSiys5GZtlwZ H3qUyIY.
The request parameter is like decrypt?param=5FHjiSJ6NOTmi7/+2tnnkQ==.
In the servlet, when I try to print the parameter by String param = request.getParameter("param"); I get 5FHjiSJ6NOTmi7/ 2tnnkQ==. It turns the character + into a space. How can I keep the orginal paramter or how can I properly handle the character +.
Besides, what else characters should I handle?
You have two choices
URL encode the parameter
If you have control over the generation of the URL you should choose this. If not...
Manually retrieve the parameter
If you can't change how the URL is generated (above) then you can manually retrieve the raw URL. Certain methods decode parameters for you. getParameter is one of them. On the other hand, getQueryString does not decode the String. If you have only a few parameters it shouldn't be difficult to parse the value yourself.
request.getQueryString();
//?param=5FHjiSJ6NOTmi7/+2tnnkQ==
If you want to use the '+' character in a URL you need to encode it when it is generated. For '+' the correct encoding is %2b
Use URLEncoder,URLDecoder's static methods for encoding and decoding URLs.
For example : -
Encode the URL param using
URLEncoder.encode(url,"UTF-8")
Back in the server side , decode this parameter using
URLDecoder.decode(url,"UTF-8")
decode method returns a String type of the decoded URL.
Allthough the question is some years old, I'd like to write down how I fixed the problem in my case: the download link to a file is created in a GWT page where
com.google.gwt.http.client.URL.encode(finalurl)
is used to encode the URL.
The problem was that the "+" sign a customer of us had in the filename wasn't encoded/escaped. So I had to remove the URL.encode(finalurl) and encode each parameter in the url with
URL.encodePathSegment(fileName)
I know my question is bound to GWT but it seems, URLEncoder.encode(string, encoding) should be applied to the parameter only aswell.