java.lang.IllegalArgumentException error on Retrofit - android

i want to get a data on Internet use Retrofit Library
my code look like this :
#GET("?key={key}&q={quotes}")
Call<List<Pixabay.hits>> getTheData(#Query("key") String key, #Query("quotes") String quotes);
java.lang.IllegalArgumentException: URL query string key={key}&q={quotes} must not have replace block. For dynamic query parameters use #Query.
for method api.getTheData
I get that problem, how to solve this? thank you.

you don't have to write query parameters in your path.
#Query will do that for you.
replace
#GET("?key={key}&q={quotes}")
with
#GET("/")
Precisely, {something} parameter can be used only in path variable.
For example,
#GET("/key/{key}")
In this case, you can use #Path annotation instead of #Query.

If you specify #GET("key?a=5"), then any #Query("b") must be appended using &, producing something like key?a=5&b=7.
If you specify #GET("key"), then the first #Query must be appended using ?, producing something like key?b=7.
So in your case no need to implement here like ?key={key}&q={quotes} just add
your domain #GET("your_domain/")

Related

Retrofit Query Annotation Without Ampersand

I am trying to make an API call to a mobile backend with Retrofit 2.0. In my API call, i have to make necessary call to this URL
https://api.backendless.com/v1/data/Users?where=followings.objectId=%270B3BA7F9-260F-B378-FF9A-3C2448B8A700%27
To form this URL in Retrofit i have been using below interface
#GET("Users?where=")
Call<List<User>> getFollowers(#Query("followings.objectId") String objectId);
This interface call puts an ampersand before the query parameters and generates a URL like below
https://api.backendless.com/v1/data/Users?where=&followings.objectId=%270B3BA7F9-260F-B378-FF9A-3C2448B8A700%27
I tried to overcome this with Path annotation but i keep getting "URL query string must not have replace block. For dynamic query parameters using #Query" error.
API that i am trying to connect requires a "where=" clause for filtering by design. I have no permission to change that. What i want is somehow tell Retrofit not to put an ampersand sign before the query parameter or any workarounds for this issue.
Any help is appreciated.
For those who seek for similar answers, I came up with below solution
I declared my interface with #Url
#GET
Call<List<User>> getFollowers(#Url String objectId);
and generated related URL part as an extension method
public String toFollowerRequest(){
return RestGlobals.BASE_URL + "Users?where=followings.objectId=%27" + objectId + "%27";
}
#GET("{path}")
Call> getFollowers(#Path("path") path, #Query("followings.objectId") String objectId);
getFollowers("Users?where=", ...)

Retrofit2: #Path parameter in OkHttp Interceptor

In our API we have sign based on both #Query and #Path parameters. Everyone suggests to use OkHttp Interceptor for this. Everything is fine with query params, but I don't think there is any way to get path parameter values and names. For example:
/api/{version}/books/{id}
/api/v1.1/books/10
To make a correct sign, I need Map:
{"id":"10", "version":"v1.1"}
Am I missing something?
Follow the following code, probably your problem will be solved.
/api/{version}/books/{id}
public type method(#Path("version") String versionValue,#Path("id") String idValue,.....)

what is the difference between #Query and #path in Retrofit?

I wanted to use retrofit library for parsing and posting the data by passing some parameters. But When defining model class some times we will use #Serialized in-front of variable, What is the use of that Serialized.And What is the difference between #Get and #Query in passing params to API.Can Any one explain the difference.
Lets say you have api method #GET("/api/item/{id}/subitem/") so by using #Path("id") you can specify id for item in path. However your api may take additional parameters in query like sort, lastupdatetime, limit etc so you add those at end of url by #Query(value = "sort") String sortQuery
So full method will look like:
#GET("/api/item/{id}/subitem")
SubItem getSubItem(#Path("id") int itemId, #Query("sort") String sortQuery, #Query("limit") int itemsLimit);
and calling api.getSubItem(5, "name", 10) will produce url #GET("/api/item/5/subitem/?sort=name&limit=10")
and #Get is HTTP method
http://www.w3schools.com/tags/ref_httpmethods.asp says
Two commonly used methods for a request-response between a client and
server are: GET and POST.
GET - Requests data from a specified resource POST - Submits data to
be processed to a specified resource
#GET is request method. You mark method with that.
#Query is query parameter (i.e. the one in the URL). You mark method parameters with that.
#Serialized probably does not belong to Retrofit, look at its package name (move cursor there and press `Ctrl+Q in Android studio)

How to add multiple of the same/array parameter using Retrofit?

I have an instance where I need to pass multiple of the same named parameters to a server (array of data).
Changing it is not a possibility.
http://test.com?test[]=1&test[]=2&test[]=3
How do I accomplish this with RetroFit? I see that you can pass a map of values, but that doesn't help as the keys are all identical.
Any help would be great... really hoping there's a clean way/workaround or else I'm going to need to use another api lib and do a project refactor.
Retrofit as of 1.4.0 added the ability to send an array or List as a #Field or #Query parameter.
New: #Query and #EncodedQuery now accept List or arrays for multiple values.
New: #Field now accepts List or arrays for multiple values.
I am using retrofit:1.9.0, one way of doing http://test.com?test[]=1&test[]=2&test[]=3 is like this
void test(#Query("test[]") ArrayList<String> values);

Android Annotations: Query params gets appended to url?

#Get("/ServiceTest?version=1&dateRange={dateRange}")
ResponseModel getDateRangeTest(String dateRange);
in RestClient interface this make the following Get
http://localhost:8080/ServiceTest/2014-01-29%25202014-01-29?version=1" resulted in 400 (Bad Request); invoking error handler
Am i doing something wrong in sending the query params.
I want address this way:
/ServiceTest?version=1&dataRange=2014-01-29%25202014-01-29
Which in this case somehow i am failed to generate with Android annotations #Get
Answer: My calls were not correct and main problem was with uri encode, correct one is
/ServiceTest?version=1&dataRange=2014-01-29%202014-01-29
you might do wrong.
Your server get /ServiceTest
but you access server with address /ServiceTest/2014-01-29%25202014-01-29
Look careful that your server receive as /ServiceTest?version=1&dateRange={dateRange}
and {dataRange} is what you intend to give as variable.
Your address should be /ServiceTest?version=1&dataRange=2014-01-29%25202014-01-29
== EDIT ==
I'm not familiar with Android Get annotation, but try this.
#Get("/ServiceTest?version=1&dateStart={dateStart}&dateEnd={dateEnd}")
ResponseModel getDateRangeTest(String dateStart, String dateEnd);
and access with /ServiceTest?version=1&dataStart=2014-01-29&dateEnd=2014-01-29
Note that I change argument for more specific. and it would be a better approach.

Categories

Resources