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.
Related
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
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());
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.
I need help. In my current development one of the requirements says:
The server will return 200-OK as a response(httpresponse).
If the panelist is verified then as a result, the server must also
return the panelist id of this panelist.
The server will place the panelist id inside the body of the 200-OK
response in the following way:
<tdcp>
<cmd>
<ack cmd=”Init”>
<panelistid>3849303</panelistid>
</ack>
</cmd>
Now I am able to put the httpresponse as
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
And I can put
String responseToClient= "<tdcp><cmd><ack cmd=”Init”><panelistid>3849303</panelistid></ack></cmd></tdcp>";
Now what does putting the above xml inside the body of 200-OK response mean and how can it be achieved?
You can write the XML directly to the response as follows:
This example uses a ServletResponse.getWriter(), which is a PrintWriter to write a String to the response.
String responseToClient= "<tdcp><cmd><ack cmd=”Init”><panelistid>3849303</panelistid></ack></cmd></tdcp>";
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
httpServletResponse.getWriter().write(responseToClient);
httpServletResponse.getWriter().flush();
You simply need to get the output stream (or output writer) of the servlet response, and write to that. See ServletResponse.getOutputStream() and ServletResponse.getWriter() for more details.
(Or simply read any servlet tutorial - without the ability to include data in response bodies, servlets would be pretty useless :)
If that's meant to be XML, Word has already spoiled things for you by changing the attribute quote symbol to ” instead of ".
It is worth having a look at JAXP if you want to generate XML using Java. Writing strings with < etc. in them won't scale and you'll run into problems with encodings of non-ASCII characters.
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.