Resteasy UriBuilder incorrectly encodes? - java

I am trying to create a URI from a string url using UriBuilder from RestEasy and I am getting some unexpected results. I am running the following piece of code.
UriBuilder uriBuilder = UriBuilder.fromPath("http://localhost:8190/items?pageNumber={pageNumber}&pageSize={pageSize}");
System.out.println(uriBuilder.build(1, 10));
Expected result:
http://localhost:8190/items?pageNumber=1&pageSize=10
Actual result:
http://localhost:8190/items%3FpageNumber=1&pageSize=10
When using UriBuilder.fromUri() instead of fromPath() it throws an exception while creating the URI
Illegal character in query at index 39: http://localhost:8190/items?pageNumber={pageNumber}&pageSize={pageSize}
the character at 39 is {.
I don't want to parse the complete string to create the URI part by part.
I looked at the RestEasy code and it is encoding the '?' character while creating the builder using org.jboss.resteasy.util.Encode#encode using the pathEncoding map from org.jboss.resteasy.util.Encode#pathEncoding.
Is my usage incorrect or the implementation incorrect?

Since RestEasy is a JAX-RS implementation, from the Oracle documentation of fromPath:
Create a new instance representing a relative URI initialized from a URI path.
I think it was not intended for absolute URLs, hence I'm afraid the answer is that your usage is incorrect.
You will need something like this (didn't test it though)
UriBuilder.fromUri("http://localhost:8190/").
path("{a}").
queryParam("pageNumber", "{pageNumber}").
queryParam("pageSize", "{pageSize}").
build("items", 1,10);

Related

How do I parse an HttpExchange request after an ending slash?

I have a request as follows:
localhost:8000/location/:01
My code takes as input an HttpContext request.
func(HttpExchange r) {
String area_path = r.getRequestURI(); // Equals string "/location/"
}
How do I parse an HttpExchange correctly so I can pull out the "01" from this path and store it as a variable?
That (localhost:8000/location/:01) is not a valid URL or URI
A plain colon character is not legal in the path of a URL or URI. If you want to put a colon in the path, it must be percent-encoded. Furthermore, if this was a URL, it would start with a protocol; e.g. http:.
Now ... it is unclear what the HTTP stack you are using will do with a syntactically incorrect URL / URI, but it could simply be ignoring the colon and the characters after it.
Your code looks a bit odd too. You have tagged the question as [java]. But the code looks like JavaScript rather than Java; i.e. func is a Javascript keyword. But it also looks like you are using the (deprecated) com.sun.net.httpserver.HttpExchange Java class. I don't know what to make of that ...
My advice:
Don't use a colon character in the URL path.
If you must do it, then percent-encode the colon it.
If you cannot encode it properly, then you may need to find and use a different framework for your HTTP request handling. One that will accept and handle a malformed URL / URI in the way that you want. (Good luck finding one!)
Unfortunately, the details in your question are too sketchy to give more detailed advice.

How to build a URI using URIbuilder without encoding hash

I have a URI like this:
java.net.URI location = UriBuilder.fromPath("../#/Login").queryParam("token", token).build();
and I am sending it as response: return Response.seeOther(location).build()
However, in the above URI, # is getting encoded to %23/. How do I create a URI with out encoding the hash #. According to official document, a fragment() method must be used to keep unencoded.
URI templates are allowed in most components of a URI but their value
is restricted to a particular component. E.g.
UriBuilder.fromPath("{arg1}").build("foo#bar"); would result in
encoding of the '#' such that the resulting URI is "foo%23bar". To
create a URI "foo#bar" use
UriBuilder.fromPath("{arg1}").fragment("{arg2}").build("foo", "bar") instead.
Looking at the example from docs, I am not sure how to apply it in my case.
The final URI should look like this:
http://localhost:7070/RTH_Sample14/#Login?token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcnRoLmNvbSIsInN1YiI6IlJUSCIsInJvbGUiOiJVU0VSIiwiZXhwIjoxNDU2Mzk4MTk1LCJlbWFpbCI6Imtpcml0aS5rOTk5QGdtYWlsLmNvbSJ9.H3d-8sy1N-VwP5VvFl1q3nhltA-htPI4ilKXuuLhprxMfIx2AmZZqfVRUPR_tTovDEbD8Gd1alIXQBA-qxPBcxR9VHLsGmTIWUAbxbyrtHMzlU51nzuhb7-jXQUVIcL3OLu9Gcssr2oRq9jTHWV2YO7eRfPmHHmxzdERtgtp348
To construct the URI with fragment use
UriBuilder.fromPath("http://localhost:7070/RTH_Sample14/").fragment("Login").build()
This results in the URI string
http://localhost:7070/RTH_Sample14/#Login
But if you also add query parameters
UriBuilder.fromPath("http://localhost:7070/RTH_Sample14/").fragment("Login")
.queryParam("token", "t").build()
then the UriBuilder always inserts the query params before the fragment:
http://localhost:7070/RTH_Sample14/?token=t#Login
which simply complies to the URL syntax.
Instead of all the hassle of redirecting without encoding the hash value. I changed my code into the following:
java.net.URI location = new java.net.URI("../#/Login?token=" + token);
So the query param above is token appended to URI location. In front-end I am using angular's location.search().token to get capture the query param.
This worked for me. Looking for better answers though. Thanks

URL percent encoding query param Bing API Java

I'm trying to URL percent encode my query param value while using URIBuilder to make an HTTP request to Bing API.
The url looks like
"https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?$format=json&Query="
Where the Query String must be like
%27Test%20query%27
Using URLEncoder.encode(string, code), a string such as "test query", gets turned into "test+query" which is unacceptable.
URIUtil.encodeQuery()
returns "test%20query" which is almost acceptable, except it needs the %27 at the beginning and end.
When I try to just concatenate the string to make it valid as such, and then load this into URIBuilder, URIBuilder ends up with
https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?%24format=json&Query=%2527test%2520query%2527
which is again unacceptable.
How can I remedy this issue? It's driving me insane.
Thanks for any help.
this is encoded URI.
$ is %24
bank is %20
if you want real URI, you need to decode .
I think decode method works well for you.
reference here:
http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/util/URIUtil.html

HTTP Get statement stops with { in URL

I'm trying to use the MapQuest API. The API is a little funny, requiring a JSON string as an input. When this code executes, I've verified the URL is correct that is strung together, but I never get to the Log.v statement after calling HTTPGet(url.toString()). I've done some research and see that this can be caused by missing certificates, but I'm only using an http connection, not https. Of course more work is done after the httpGet, but I've only posted the relevant code. No error is ever thrown, the code just simply stops executing beyond that. I've used essentially the same code, only slightly different URLs for parsing other RESTFUL APIs. Any thoughts?
private JSONObject callMapQuestGeoCoder(Location location)
{
String APIkey=decryptKey(MapQuestEncryptedKey);
StringBuilder url=new StringBuilder();
url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&callback=renderReverse");
url.append("&json={location:{latLng:{lat:"+location.getLatitude());
url.append(",lng:"+location.getLongitude());
url.append("}}}");
HttpGet httpGet = new HttpGet(url.toString());
Log.v(TAG,""+httpGet);
EDIT: Per advice, I stuck the code in a try catch, and got this stack trace (Modified only to remove my API Key, and change the location slightly). The character that isn't valid is the { character.
10-26 17:42:58.733: E/GeoLoc(19767): Unknown Exception foundjava.lang.IllegalArgumentException: Illegal character in query at index 117: http://open.mapquestapi.com/geocoding/v1/reverse?key=API_KEY&callback=renderReverse&json={location:{latLng:{lat:33.0207687439397,lng:-74.50922234728932}}}
According to the URI Specification (RFC 3986), the curly bracket characters are neither "reserved characters" or "unreserved characters". That means that they can only be used in a URL (or any other kind of URI) if they are "percent encoded".
Your URL contains plain (unencoded) curly bracket characters. That is invalid according to the spec ... and it is why the HttpGet constructor is throwing an exception.
Pearson's answer gives one possible way to create a legal URL. Another would be to assemble the URL using a URI object; e.g.
url = new URI("http", "open.mapquestapi.com", "/geocoding/v1/reverse",
("key=" + APIkey + "&callback=renderReverse" +
"&json={location:{latLng:{lat:" + location.getLatitude() +
",lng:" + location.getLongitude() + "}}}"),
"").toString();
The multi-argument URI constructors take care of any required encoding of the components ... as per the specific details in the respective javadocs. (Read them carefully!)
The issue is that the use of { is illegal in an HTTP get. The solution is to run the URL through a "Safe URL Encoder". The trick, per this question, is to ensure that you only run it through the part of the URL that needs it, and don't include things like &, http://, etc.
url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&callback=renderReverse");
url.append(URLEncoder.encode("&json={location:{latLng:{lat:"+location.getLatitude(),"UTF-8"));
url.append(",lng:"+location.getLongitude());
url.append(URLEncoder.encode("}}}","UTF-8"));
And the even better solution, use the non-JSON input API for Mapquest. The output still is JSON.
url.append("http://open.mapquestapi.com/geocoding/v1/reverse?key="+APIkey);
url.append("&lat="+location.getLatitude());
url.append("&lng="+location.getLongitude());

Android java.io.IOException: java.net.URISyntaxException:

I'm getting an exception saying Java URI Syntax Exception "java.io.IOException: java.net.URISyntaxException: Invalid % sequence: %wl in query at index 88:" when i try to connect from my android application.
It seems to be throwing the exception where in the URL it says "%wl" and following is the URL. is there a work around for this.
http://192.168.111.111:9000/RB/db.svc/upd?LinkId=184617ED1F21&IPs=fe80::1a46:17ff:feed:1f21%wlan0,192.168.1.127,&MNo=0771111111&sPin=000&Status=0
If you want to use % in your URL the first you need to do is to encode it.
So first you need to replace that % with %25 in your string ....1f21%wlan0... with .....1f21%25wlan0.... before connecting.
You can use the following code for encoding the URL in Java
String encodedUrl = java.net.URLEncoder.encode(<your_url>,"UTF-8");
Have a look at the below links for more information.
1.How to encode url in java
2.URL encoding character reference
UPDATE :
If you don't want to use URL encoder then you can try this out :
yourURL.replaceAll("%", "%25");
It is fine here to replace a single special character, but it would be a tedious task to do like this if you have many special characters that require proper URL encoding.

Categories