Android Volley MalformedURLException Bad URL - android

After making a second network request using Volley, I always get this error. It doesn't seem to matter what the url I put in is. Volley always claims it is malformed.
08-04 20:16:26.885 14453-14470/com.thredup.android E/Volley﹕ [994] NetworkDispatcher.run: Unhandled exception java.lang.RuntimeException: Bad URL
java.lang.RuntimeException: Bad URL
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:127)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
Caused by: java.net.MalformedURLException: Protocol not found:
at java.net.URL.<init>(URL.java:176)
at java.net.URL.<init>(URL.java:125)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:101)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)
Investigating further, I put a couple logs in HurlStack. In
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders),
the request that fails is REQUEST [ ] 0x0 LOW 26."
Thus, line 101 of HurlStack : URL parsedUrl = new URL(url);
fails with an empty url (request.getUrl() is empty).
I am using OkHttpStack (extending HurlStack).
Any ideas on what could be causing this?

actually the problem is with your url not with the volley. Your Url is not a URI. There is no protocol component in it. It needs http:// or whatever other protocol you intend. If you have the http in your url make sure where it is correctly formed or not.
For example your url formation should be like this
public String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
Don’t forget to read the URL Specification and make sure the URL you are providing is valid.

Make Sure that you have passed the URL as the second parameter in JsonObjectRequest or StringRequest. I made the same mistake which produced the same error like what you faced.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Method.POST, URL, null, ResponseListener, ErrorListener);

Use
http://
OR
https://
prefix to your URL
example:
example.com/information.json
write it as
http://example.com/information.json

this Exception occur while you are hitting an Url that is not prefixed withhttp// or https//.so check there is therehttp// is with your URL.
you can get more information here and see these links

Related

Android Volley: How to flush and disable cache?

On my Android phone, I use Volley to do an HTTP POST request. The server sent an error response indicating a problem in the JSON data that I have passed. I have fixed the error but the server still display the same error. I have tried to pass an empty JSON file and I still get the same error response so the response clearly comes from some cached data.
I have tried to use those 2 things to clear and disable the cache but it doesn't help:
mRequestQueue = Volley.newRequestQueue(this);
mRequestQueue.getCache().clear(); // <==== Here
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST, url, dataObject, ...);
jsonObjReq.setShouldCache(false); // <==== Here
mRequestQueue.add(jsonObjReq);
How can I disable the Cache used by Volley or Android?
If I use Curl to execute the same request it works.
Thanks
I have been able to fix the issue. I was using JsonObjectRequest and the server didn't understand the JSON file that I was sending.
I'm now using StringRequest() and it works.
Here is the non working code using JsonObjectRequest:
https://www.thethingsnetwork.org/forum/t/error-when-trying-to-add-an-end-device-from-http-api/55088/18?u=oliviergrenoble
And here is the working code using StringRequest:
https://www.thethingsnetwork.org/forum/t/error-when-trying-to-add-an-end-device-from-http-api/55088/21?u=oliviergrenoble
I have probably done something wrong in JsonObjectRequest version!

How to avoid MalformedURLException when URL is "data:text/html"?

In my WebView-based app, when the app accesses http://mobile.nytimes.com/ my WebViewClient receives 6-7 onPageFinished(), the first 3-4 with WebView.getUrl() returning the original URL (http://mobile.nytimes.com/) but then it returns "data:text/html" for the rest.
Apparently, data:text/html is a valid URI. Also see https://url.spec.whatwg.org/#fetch-scheme .
However, in my code, I need to instantiate a URL from WebView's url like this:
new URL(myWebView.getUrl());
and unfortunately this throws a MalformedURLException when WebView.getUrl() returns 'data:text/html'.
Is there a way to convert the 'data:text/html' string to a valid URL string so that new URL() will not throw the MalformedURLException?
As you wrote data: is a valid URI not an URL. https://en.wikipedia.org/wiki/Data_URI_scheme

java.lang.IllegalArgumentException: Illegal URL with retrofit

i'm trying to call an api in my application
i've the following url template
test-test.domainname.com/feeds/json/v3/attribute/attribute
i'm using retrofit 2
but i get the following fatal exception
Illegal URL: test-test.domainname.com
and this is my interface
public interface Iinterface{
#GET("feeds/json/v3/attribute/"+attribute)
Call<ArrayList<result>>getresult();
}
can someone help me with this problem ...
my base URL is here: http://myapiname.azurewebservices.net
and feed method is like that :
public interface Iinterface{
#GET("/feeds/json/v3/attribute/"+attribute)
Call<ArrayList<result>>getresult();
}
And working perfectly. Please add http or https and try again
You do not have a protocol section. Prepend http:// or https:// depending on which applies to your url --
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://test-test.domainname.com")
// ... other retrofit options
.build();
In my case,
my base url contained space character. (eg. http://myapiname.azure webservices.net )
I fixed this Error by removing space in my base URL.
Illegal URL Exception in retrofit is triggered when your passed url is
not really existed or not fix with url standard.
By mistake, I provided empty string to baseUrl() so because of this i was getting java.lang.IllegalArgumentException: Illegal URL exception.

Missing parameter access_token on OAuth2 request

I'm using the Apache Amber libraries to try to retrieve an OAuth2 access token from a Web site under my control. My client code is running under Android.
My code is patterned on the example at:
https://cwiki.apache.org/confluence/display/AMBER/OAuth+2.0+Client+Quickstart
In the first step, I'm able to retrieve a "code" by submitting a GET request using a WebView browser:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.buildQueryMessage();
webview.loadUrl(request.getLocationUri());
I use a WebViewClient callback to capture the redirect URL with the "code" parameter. So far, so good.
Using that code, I try to retrieve my access token:
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.buildBodyMessage();
GitHubTokenResponse oAuthResponse =
oAuthClient.accessToken(request, GitHubTokenResponse.class);
Each time I run my code, I get an OAuthProblemException, where the message is that I have an invalid request due to a missing parameter, access_token.
Another StackOverflow post mentions this exception from a similar OAuth2 request, which in that case was caused by having different redirect URIs across OAuth requests. But I've made sure my redirect URIs are the same by using a named constant. Here's the link to that post:
OAuthProblem, missing parameter access_token
Now, I can print out the code returned by the first request, and paste it into a curl command run from my desktop machine:
curl -d "code=...&client_id=...&client_secret=...&grant_type=...&redirect_uri=..." http://my_website.com
and I get a nice JSON response from my site with an access_token.
Why does the call from Java fail, where my hand-rolled command line succeeds?
I had the same problem implementing the client and the server, the problem is about one mistake in the Client Example in the Apache Amber (Oltu) project:
First you have the Auth code request (which work):
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.**buildQueryMessage**();
And second the request about the Access Token (which don't work):
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.**buildBodyMessage**();
The mistake is about the buildBodyMessage() in the second request. Change it by buildQueryMessage().
Solved in my case.
Amber/Oltu "Missing parameter access_token" error may mean that GitHubTokenResponse or OAuthJSONAccessTokenResponse are unabled to translate response body for any reason. In my case (with Google+ oAuth2 authentication), the response body, is not parsed properly to the inner parameters map.
For example:
GitHubTokenResponse
parameters = OAuthUtils.decodeForm(body);
Parse a form-urlencoded result body
... and OAuthJSONAccessTokenResponse has the next parse function
parameters = JSONUtils.parseJSON(body);
This JSONUtils.parseJSON is a custom JSON parser that not allow for me JSON response body from GOOGLE+ and throws an JSONError (console not logged),
Each error throwed parsing this parameters, are not console visible, and then always is throwed doomed "Missing parameter: access_token" or another "missing parameter" error.
If you write your Custom OAuthAccessTokenResponse, you can see response body, and write a parser that works with your response.
This is what I encountered and what I did to get it working:
I quickly put together a similar example described in:
https://cwiki.apache.org/confluence/display/OLTU/OAuth+2.0+Client+Quickstart
and:
svn.apache.org/repos/asf/oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/OAuthClientTest.java
This was my command to execute it:
java -cp .:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I also ended up with the above mentioned error where the access_token was expected. I ended up debugging in intellij and traced an anomaly with the if condition which checks that the string begins with the "{" character.
In doing so, I also added the following jar to my classpath so that I may debug the trace a little deeper.
./java-json.jar
(downloaded from http://www.java2s.com/Code/Jar/j/Downloadjavajsonjar.htm)
During the next debug session, the code actually started working. My mate and I eventually found the root cause was due to the JSON jar not being included.
This is the command which works:
java -cp .:./java-json.jar:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I was having the same problem when trying to get the access token from fitbit OAuth2. buildBodyMessage() and buildQueryMessage() were both giving me missing parameter, access_token.
I believe this is something to do with the apache oauth2 client library. I ended up making simple post requests using spring's RestTemplate and it's working fine.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + "MjI5TkRZOjAwNDBhNDBkMjRmZTA0OTJhNTE5NzU5NmQ1N2ZmZGEw");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", FITBIT_CLIENT_ID);
map.add("grant_type", "authorization_code");
map.add("redirect_uri", Constants.RESTFUL_PATH + "/fitbit/fitbitredirect");
map.add("code", code);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(FITBIT_TOKEN_URI, request, String.class);
log.debug("response.body: " + response.getBody());

How can I use http auth information from a URL in Android?

In my browser, or in iOS, when I try to get the contents of a URL with encoded http authentication information in the form
http://myUser:myPassword#www.example.com/secure/area/index.html
It just works. I'm getting URLs from a web service, and I'd like to avoid trying to parse them up for their HTTP auth info if I can help it. Is there a way to do something similar in Android without actually parsing the URLs? Alternatively, what is the best way to go about that?
UPDATE:
I find that when I try to set the authentication information in an Authorization header, I get a very strange FileNotFoundException.
Here's the code I'm using:
URL url = new URL(urlString);
URLConnection connection;
String authority = url.getAuthority();
if (authority.contains("#")) {
String userPasswordString = authority.split("#")[0];
url = new URL(urlString.replace(userPasswordString + "#", ""));
connection = url.openConnection();
String encoded = new String(Base64.encode(userPasswordString.getBytes(), Base64.DEFAULT), "UTF-8");
connection.setRequestProperty("Authorization", "Basic " + encoded);
} else {
connection = url.openConnection();
}
InputStream responseStream = connection.getInputStream();
All the info seems to check out, I've verified the url is correct, the base64 string is correct, and the file is certainly on the server--I have no trouble at all opening it with Firefox, and Firebug shows all the right headers, matching what I've sent as far as I can tell. What I get though is the following error (url host changed to protect the innocent):
java.io.FileNotFoundException: http://a1b.example.com/grid/uploads/profile/avatar/user1/custom-avatar.jpg
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1061)
Any idea what this is all about?
I looked into using HttpClient, but saw that in Issue 16041 it is recommended that we prefer URLConnection.
That looks like your browser is applying some extra rules to parsing the URL. In Android you can use HTTP Client's authentication mechanism such as BASIC and DIGEST to do the same things. Which one you choose is dependent on the server you are trying to authenticate against.
Here is a good page to get you started.
Unfortunately, on Android you can't pass the user info (username/password) in that format to either java.net.URL or HttpClient and have it work like in a browser.
I'd recommend using URI (see http://download.oracle.com/javase/1.5.0/docs/api/index.html?java/net/URI.html) to do this: pass your URL to the URI constructor that takes a String and then you can extract the user info (using getUserInfo()). You can then either use HttpClient's authorization classes (see http://developer.android.com/reference/org/apache/http/auth/package-summary.html) or build the basic auth header yourself (an example is given at http://www.avajava.com/tutorials/lessons/how-do-i-connect-to-a-url-using-basic-authentication.html).

Categories

Resources