How to use #Query in URL in Retrofit? - android

Hi all i call below URL using Retrofit
https://api.stackexchange.com/2.2/me?key=gQJsL7krOvbXkJ0NEI((&site=stackoverflow&order=desc&sort=reputation&access_token=HM*22z8nkaaoyjA8))&filter=default
and for that i created Interface RestInterface
//get UserId
#GET("/me&site=stackoverflow&order=desc&sort=reputation&access_token={access_token}&filter=default")
void getUserId(#Query("key") String apikey,#Path("access_token") String access_token,Callback<UserShortInfo> cb);
When i do this it always add key at the end of the URL(Output below).
I added #Query("key") as Query Parameter becoz it's dynamic.
http://api.stackexchange.com/2.2/me&site=stackoverflow&order=desc&sort=reputation&access_token=p0j3dWLIcYQCycUHPdrA%29%29&filter=default?key=gQJsL7krOvbXkJ0NEI%28%28
and that's the wrong. I got HTTP 400. Also here (( and )) converted into %28%28 and %29%29
Please help me how to make
https://api.stackexchange.com/2.2/me?key=gQJsL7krOvbXkJ0NEI((&site=stackoverflow&order=desc&sort=reputation&access_token=HM*22z8nkaaoyjA8))&filter=default
in Retrofit. I want it add #Query parameter in between URL. not at the end of the URL

Don't put query parameter inside the URL only the path parameter you can add
#GET("/me?site=stackoverflow&order=desc&sort=reputation&filter=default)
void getUserId(#Query("key") String apikey,#Query("access_token") String access_token,Callback<UserShortInfo> cb);
#Query("access_token") --> given key and value will come query URL
While sending request your URL form will like below
/me?key=?site=stackoverflow&order=desc&sort=reputation&filter=default&"your_value"&access_token="your_value"

obviously instead
#GET("/me&site=stackoverflow&order=desc&sort=reputation&access_token={access_token}&filter=default")
void getUserId(#Query("key") String apikey,#Path("access_token") String access_token,Callback<UserShortInfo> cb);
you should use
#GET("/me?site=stackoverflow&order=desc&sort=reputation&filter=default")
void getUserId(#Query("key") String apikey,#Query("access_token") String access_token,Callback<UserShortInfo> cb);
the chanege is /me& to /me? ... (and second is to use access_token as Query param too, not as a Path)
edit more explanations:
After parsing url which looks like (me&)
scheme:host/me&blablalbal=blalbla&blabla=blabla
the path is
me&blablalbal=blalbla&blabla=blabla
and there is no query paramas at all ... so adding params end with adding ?param=value at the end
but with (me?)
scheme:host/me?blablalbal=blalbla&blabla=blabla
the path is
me
and there are already some query parameters ... so addin new end with adding &param=value at the end :)

Related

Android: Path parameters in HTTP get method by retrofit

I have this api link:
http://www.xxxx.com/?apikey=mykey&i=tt036543
Now by retrofit I am trying to call this api with GET method so I can create this interface:
#GET("/?apikey=mykey&i={movie_id}")
Call<MovieDetailEntity> getSearchedMovie(#Path("movie_id") String id);
But I got this error:
java.lang.IllegalArgumentException: URL query string "apikey=mykey&i={movie_id}" must not have replace block. For dynamic query parameters use #Query.
for method BatmanService.getSearchedMovie
If I use this Query :
#GET("/?apikey=mykey&i=")
Call<MovieDetailEntity> getSearchedMovie(#Query("movie_id") String id);
Then the link changes to :
http://www.xxxx.com/?apikey=mykey&i=&movie_id=tt036543
How can I call this api?
If I remember well once you use #query you should not set the variable at the url. It will use the string inside the #query annotation as the variable name.
This should work:
#GET("/?apikey=mykey")
Call<MovieDetailEntity> getSearchedMovie(#Query("i") String id);
And also this, if you want to pass your api key as well:
#GET("/")
Call<MovieDetailEntity> getSearchedMovie(#Query("apikey") String mykey,
#Query("i") String id);
The ? and & are automatically added for you.

Encoding in retrofit url with GET method

I am not able to add special character "&" in my endpoint of the URL.
Here is my api interface
#GET("api/v1/products/artworks/")
Call<TaskData> getLatestTaskData(#Header("Authorization") String token,
#Query("limit") Integer limit,
#Query("offset") String offset);
URL that is getting called
artworks/?limit=50&offset=0%26ordering%3D-artwork
And this is how I am calling the api
String url = Integer.toString(totalitemsCalledLatest) +"&ordering="+ ordering;
Call<TaskData>
call = taskApiInterface.getLatestTaskData("Token "+ user_token, 50, url);
My ordering string is something like &medium=1&base=2
But it converts automatically & to %26 and = to %3D
edit: assuming you are having connection problems to the api, i think you just need to remove the '/' from the end of your GET URL, like this: api/v1/products/artworks or at least that is one solution that will help you get closer to fixing your problem

Custom parameter with Retrofit2

I want to customizer my endPoint using Retrofit2 on Android but I have a doubt.
If I do that:
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(#Query("one") String one, #Query("two") String two,
#Query("key") String key)
My endPoint could be like this:
//-> https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434
I'm working with this endPoint:
// -> https://example.com/third-party-public/categories/category_id.json
If I use the same ideia as I explained above the result can be is:
#GET("/third-party-public/categories/")
Observable<List<Category>> getCategoryDetail(#Query(".json") String category_id);
The result could be:
// -> https://example.com/third-party-public/categories/.json=1
But I want that result
// -> https://example.com/third-party-public/categories/1.json
How can I setting my #query for get that result?
#GET("/third-party-public/categories/{category_id}.json")
Observable<List<Category>> getCategoryDetail(#Path("category_id") String category_id);
If you set a request with query it sets as query param '?'.
If the result you want is that you simply use it as in path:
#GET("Search/{fileUri}")
Call<Products> getProducts(#Path("fileUri") String fileUri);
You get the value it as "1.json".

Retrofit: how fix "only one http method is allowed. found: get and get"?

I have that structure for request.
Request getTransportByStation work perfectly.
But I get exception java.lang.IllegalArgumentException: TransportWebService.getTransportByRoute: Only one HTTP method is allowed. Found: GET and GET.
I found solution only for POST and POST.
interface TransportWebService {
#GET(QUERY_CATEGORY_TRANSPORT + "GetTransportByNextStation/{station}")
Observable<ResponseRouteList> getTransportByStation(
#Path("city") String city,
#Path("station") String station,
#Query("count") int count,
#Query("userid") String userId
);
#GET(QUERY_CATEGORY_TRANSPORT + "GetTransportByRoute/{route}")
Observable<ResponseRouteList> getTransportByRoute(
#Path("city") String city,
#Path("station") String route,
#Query("count") int count,
#Query("userid") String userId
);
#GET(QUERY_CATEGORY_TRANSPORT + "Time")
Observable<Integer> getTime(
#Path("city") String city
);
}
UPD: Retrofit version 1.9.0
Init service like this
private static final TransportWebService SERVICE = Common.getRestAdapter()
.setConverter(new GsonConverter(new Gson())
.build()
.create(TransportWebService.class);
In the second GET method, the second argument (#PATH("station")) should be #PATH("route").
I had the same error found: POST and POST, my issue was that I was missing a path parameter in my URL but I was sending it along with the request.
I was hitting the URL without last parameter.
http:www.webtest.requestService/customerapp/{context}/{token}/services/{flightLegId}/
Actual URL was should be:
http:www.webtest.requestService/customerapp/{context}/{token}/services/{flightLegId}/{flightLegExtId}/
This may happen because of tiny mistake like if you are giving parameter like instead of {id}.
The error the "GET and GET" or "POST and POST" error is masking the root exception. It seems the most common exception is that your argument in the HTTP argument method does not match the argument in your Path parameter.
The {id} in #GET("/objects/{id}") must match id in #Path("id").

Batch request using Retrofit

I'd like to perform batch request using Retrofit. It there any nice way, how to achieve it? Basically what I'm trying to do is to replace some characters in query part of URL (replace block is allowed only in path part of URL - using #Path annotation).
Here is a pseudocode for my problem.
#GET("/v2/multi?requests=/users/self,/venues/search?client_id={client_id}&client_secret={client_secret}&v={v}&ll={ll}&intent={intent}&limit={limit}")
ProfileSearchVenuesResponse searchVenuesAndProfiles(#ReplaceBy("client_id") String clientId,
#ReplaceBy("client_secret") String clientSecret,
#ReplaceBy("v") int version,
#ReplaceBy("ll") String location,
#ReplaceBy("intent") String intent,
#ReplaceBy("limit") int limit);
#Query is what you are looking for:
#GET("/v2/multi?requests=/users/self,/venues/search")
ProfileSearchVenuesResponse searchVenuesAndProfiles(
#Query("client_id") String clientId,
#Query("client_secret") String clientSecret,
#Query("v") int version,
#Query("ll") String location,
#Query("intent") String intent,
#Query("limit") int limit);
In version 1.7.0 of Retrofit (released yesterday) the exception message for attempting to use #Path in the original question instructs you as to the right solution:
URL query string "client_id={client_id}&client_secret={client_secret}&v={v}&ll={ll}&intent={intent}&limit={limit}" must not have replace block. For dynamic query parameters use #Query.

Categories

Resources