"Illegal Characters" in URL for HttpGet in Android get double-encoded - java

I am trying to find a solution to this the whole evening now...
I write an app which requests data from a web server. The Server answers in JSON format.
Everything works well except when I enter a umlaut like ä into my App.
In the following I assume the request URL is http://example.com/?q= and I am searching for "Jäger"
The correct call would then be h++p://example.com/?q=J%C3%A4ger
(Sorry for plus-signs but the spam protection doesnt let me post it correctly.)
So my problem is now:
When I give my URL String encoded or unencoded over to HttpGet it will always result in a doublee-encoded URL.
The Request to my Server is then http://example.com/?q=J%25C3%25A4ger (It encodes the percent signs)
which leads to the server searching in database for J%C3%A4ger what is obviously wrong.
So my question is how can I achive that if the user enters "Jäger" my app calls the correctly encoded URL?
Thanks for any help!
Here is the currently used code... Ist probably the worst possible idea I had...
URI url = new URI("http", "//example.com/?q=" + ((EditText)findViewById(R.id.input)).getText().toString(), null);
Log.v("MyLogTag", "API Request: " + url);
HttpGet httpGetRequest = new HttpGet(url);
// Execute the request in the client
HttpResponse httpResponse;
httpResponse = defaultClient.execute(httpGetRequest);

Update: Sorry, HttpParams isn't meant for request parameters but for configuring HttpClient.
On Android, you might want to use Uri.Builder, like suggested in this other SO answer:
Uri uri = new Uri.Builder()
.scheme("http")
.authority("example.com")
.path("someservlet")
.appendQueryParameter("param1", foo)
.appendQueryParameter("param2", bar)
.build();
HttpGet request = new HttpGet(uri.toString());
// This looks very tempting but does NOT set request parameters
// but just HttpClient configuration parameters:
// HttpParams params = new BasicHttpParams();
// params.setParameter("q", query);
// request.setParams(params);
HttpResponse response = defaultClient.execute(request);
String json = EntityUtils.toString(response.getEntity());
Outside of Android, your best bet is building the query string manually (with all the encoding hassles) or finding something similar to Android's Uri.Builder.

Related

java.net.URISyntaxException: Illegal character in query at index 177

I tried to get Azure Usage details via nextLink which is shared by Azure. while i tried to make http request URISyntaxException is occured.
HttpClient httpclient = getHttpClient();
URIBuilder uriBuilder=new URIBuilder(url);
HttpGet httpGet = new HttpGet(uriBuilder.build());
HttpResponse httpResponse = httpclient.execute(httpGet);
This is the nextLink url:
"https://management.azure.com/subscriptions/78c50b17-61fd-40cc-819c-4953586c7850/providers/Microsoft.Consumption/usageDetails?api-version=2019-11-01&$filter=properties/usageStart eq '2020-07-1' and properties/usageEnd eq '2020-07-30' &metric=actualcost&$expand=properties/meterDetails,properties/additionalInfo&sessiontoken=15:785628&$skiptoken=827CDTHDWI07C46616C7365730&skiptokenver=v1&id=2d790-d675-45d-89j56-3989w06cca"
I think this is because of characters such as ?, & and ! in my URL. so I tried using:
URLEncoder.encode(myUrl, "UTF-8");
but after this, I faced protocol exception.
Am I missing something here?
Your URL contains spaces and single quotes, these should be URL encoded like you tried. However, because you tried to URL-encode the entire URL, you end up with this:
https%3A%2F%2Fmanagement.azure.com%2Fsubscriptions%2F78c50b17-61fd-40cc-819c-4953586c7850%2Fproviders%2FMicrosoft.Consumption%2FusageDetails%3Fapi-version%3D2019-11-01%26%24filter%3Dproperties%2FusageStart+eq+%272020-07-1%27+and+properties%2FusageEnd+eq+%272020-07-30%27+%26metric%3Dactualcost%26%24expand%3Dproperties%2FmeterDetails%2Cproperties%2FadditionalInfo%26sessiontoken%3D15%3A785628%26%24skiptoken%3D827CDTHDWI07C46616C7365730%26skiptokenver%3Dv1%26id%3D2d790-d675-45d-89j56-3989w06cca
Which is not a valid URL. You could simply try using a naive form of String replacement:
myUrl = myUrl.replace(" ", "%20").replace("'", "%27");
If that is not sufficient, you'll need to reconstruct the URL yourself, and only apply URL-encoding on the query parameter values.

In Java "&curren" is encoded to "¤". How to prevent this

From Java code I want to call a webservice like this:
"http://example.com/mytarget?firstParam=xxx&currency=EUR"
But no matter what I do. As soon as I compose a String with "&currency=" in it, it gets replaced by "¤cy=" instantly, which the webservice doesn't like and responds with an error.
To illustrate, here is a small code snipet I use:
String uri = "http://example.com?test=1&currency=EUR";
HttpGet request = new HttpGet(uri); //string got replaced already!
request.addHeader("content-type", "application/json");
HttpResponse result = httpClient.execute(request);
String json = EntityUtils.toString(result.getEntity(), "UTF-8");
The above code makes a call to:"http://example.com?test=1¤cy=EUR"
Similar Question, no answer:
https://stackoverflow.com/questions/29890388/how-to-get-curren-to-display-literally-not-as-an-html-entity-in-Java
Any ideas?
Or is there a "proper" way to call a webservice from Java code that avoids this problem?

Handling HTTP request redirect in java

I'm writing a network android application that uses http requests to get data. The data is HTML format. I use Apache HttpClient and JSoup.
When I'm out of traffic with my mobile internet provider, I am always redirected to the providers' page saying that I should pay some money. Of course, it is a bad idea to parse this page.
How to detect occured page substitution?
This code will help you to know with is the final target of your request, if isn't the page that you asked for, is the provider page.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpget = new HttpGet("http://www.google.com/");
HttpResponse response = httpclient.execute(httpget, localContext);
HttpHost target = (HttpHost) localContext.getAttribute(
ExecutionContext.HTTP_TARGET_HOST);// this is the final page of the request
System.out.println("Final target: " + target);
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
Thanks
If your provider is lying to you by immediately returning a 200 OK but not giving you the resource you've requested, your best option is probably to set a custom HTTP response header that your client can check before continuing.

Apache Httppost retrieve image from server Java

Right now I am using Httppost to Post some parameters in the form of xml to a server. When the post occurs, a geotiff or .tif file is downloaded. I have successfully posted the document to the server and successfully downloaded the file simply by attaching the parameters to the url but I can't seem to combine the two. I have to use post because just using the URL leaves out elevation data in the geotiff.
In short, I am not sure how to simultaneously post and retrieve the image of the post. This is what I have thus far...
// Get target URL
String strURL = POST;
// Get file to be posted
String strXMLFilename = XML_PATH;
File input = new File(strXMLFilename);
// Prepare HTTP post
HttpPost post = new HttpPost(strURL);
post.setEntity(new InputStreamEntity(
new FileInputStream(input), input.length()));
// Specify content type and encoding
post.setHeader(
"Content-type", "text/xml");
// Get HTTP client
HttpClient httpclient = new DefaultHttpClient();
//Locate file to store data in
FileEntity entity = new FileEntity(newTiffFile, ContentType.create("image/geotiff"));
post.setEntity(entity);
// Execute request
try {
System.out.println("Connecting to Metoc site...\n");
HttpResponse result = httpclient.execute(post);
I was under the impression that the entity would contain the resulting image. Any help is much appreciated!
Thanks for the help guys. The entity was what was being sent to the server. I had code that was trying to read it from the response as well but it wasn't working because setting the entity to a file entity messed up the post request. By removing that part, it works great!

android HTTP POST fail

I'm trying to connect and post to a simple java webservice, running the post's URL from chrome succeeded, but android code skip the following lines (without throwing errors), but the webservice doesn't accept the post
HttpPost post = new HttpPost(setFacebookEventsAddress+userId+"/"+accesstoken);
post.setHeader("Accept", "application/json");
post.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(post);
the webservice method signature handling the above request:
#GET
#Path("setData/{user_id}/{accessToken}")
#Produces(MediaType.APPLICATION_JSON+ ";charset=utf-8")
public String setData(#PathParam("user_id") String user_id,
#PathParam("accessToken") String accessToken) {
since I manage to post throw my browser, anyone can help with what's wrong with my android code?
URL url = new URL(setFacebookEventsAddress+userId+"/"+accesstoken);
HttpURLConnection con = (HttpURLConnection) url
.openConnection();
ja = readStream(con.getInputStream());
Using HttpURLConnection instead of HttpPost did the trick for me, thanks for all the helpers!
It is not possible to say with any certainty (given the evidence), but my guess would be that the expression
setFacebookEventsAddress + userId + "/" + accesstoken
is evaluating to a different URL to the one you are using from the web browser.
I suggest that you try the following:
Turn on request logging on your server, and compare the URLs in the requests being sent.
Modify your client to print out the response status code and the response body. The latter is likely to be an error page that will give you more clues.
Another possible problem is that your code doesn't appear to be sending any body with the POST request.
On revisiting this, the problem was that you were using / trying to do a POST to a web service that you had configured to support GET only. I expect that if you had looked at the status code you would have found that the response code was "Method not supported".

Categories