Hello I am trying to use #Query in retrofit but I am getting error something like this :-
must not have replace block. For dynamic query parameters use #Query.
here is my interface :-
public interface Parser {
#GET("weather?q={city}&appid=0a8")
Call<Model> getModel(#Query("city") String city);
}
And this is in my Activity :-
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("xyz/")
.addConverterFactory(GsonConverterFactory.create())
.build();
Parser parser = retrofit.create(Parser.class);
Call<Model> call = parser.getModel("london");
Thanks in advance
if your api query should be like -
BASE_URL/weather?q=london&appid=0a8
Then use
#GET("weather")
Call<Model> getModel(#Query("q") String city,#Query("appid") String app_id);
In this case you should use #Path instead of #Query
public interface Parser {
#GET("weather?q={city}&appid=0a8")
Call<Model> getModel(#Path("city") String city);
}
Related
This is my Api.php
$command=$_POST["command"];
if($command=="getUsers"){
getUsers();
}
elseif ($command=="getNews")
{
getNews();
}
I'm using retrofit to show result in my android app. I need to pass parameter Command through Retrofit Post and Get a result at the same time.
what's the solution?
Try like this example from Retrofit website:
#FormUrlEncoded
#POST("user/edit")
Call<User> updateUser(#Field("first_name") String first, #Field("last_name") String last);
Source: https://square.github.io/retrofit/
I have an Api https://hello.example.com:344/new/search/result.
Implementing same using Retrofit 2:
This is how initialising retrofit:
public static void initializeRetrofit() {
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://hello.example.com:344")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
service2 = retrofit.create(ContentService.class);
}
This is the interface request:
#POST("new/search/result")
Call<JsonObject> getSearchList(#Body JsonObject request);
But when i hit api : it removes the port from it and hits
"https://hello.example.com/new/search/result"
What is going wrong?
In your base url "https://hello.example.com:344" transform it to
"https://hello.example.com:344/"
There is no / (slash) in your base url as well as in the interface function. So the request becomes like "https://hello.example.com:344new/search/result " which will give u an error.
Add slash at the end of your base url like this "https://hello.example.com:344/"
I want to ask that do I need to create new Interfaces for every POST GET request I make which have different URL .
For ex
I made 1 interface for register and other for Login other for getting Friends. Cant I just make 1 general post and get method where I can send URL , params to send and record response?
No you don't need to create new interface or new client for each request!
Inside a interface you can create multiple method as you want and as your requirement.
For Login and fro Registration method name will be different, your parameter will not same. So you can create method as you need.
//When Base Url like "http://exmaple.com/"
#GET("Service/registration")
Call<RegResult> getRegistered(#Query("name") String name,
#Query("email") String email,
#Query("dob") String dob,
#Query("name") String name
);
#GET("Service/login")
Call<LoginResult> getLogin(#Query("username") String username,
#Query("pass") String pass
);
#GET("Service/profile")
Call<ProfileResult> getProfile(#Query("userid") String userid
);
You can also use same client because your base url is same.
If base url is diffrent you can also use same client like this..
public class ApiClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String base_url) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(base_url)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
Now you can set different base url.
Creating object of interface...
String BASE_URL = "http://exmaple.com/";
ApiInterface apiService = ApiClient.getClient(BASE_URL).create(ApiInterface.class);
Calling method..
String user_id = "1";
Call< ProfileResult > call = apiService.getProfile(user_id);
Getting result
call.enqueue(new Callback< ProfileResult >() {
#Override
public void onResponse(Call< ProfileResult >call, Response< ProfileResult > response) {
Profile profile = response.body().getResults();
}
#Override
public void onFailure(Call< ProfileResult >call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
Hop you got your answer .... for farther query fill free to ask...
I have dynamic JSON, here is example: http://pastebin.com/QMWRZTrD
How I can parse it with Retrofit?
I failed to generate POJO classes, since I have dynamic fields like "5411" and "5412".
EDIT:
I solved it by using Map, since first value is always integer, and second is list of objects.
#FormUrlEncoded
#POST("history.php")
Observable<Map<Integer, List<Vehicle>>> getHistory(#Field("uredjaji") String vehicleId, #Field("startDate") String startDATE, #Field("endDate")
you can use Map to serialize and deserialize it in case of Random keys.
Observable<Map<Integer, List<YourObject>>>
You can get retrofit api call to return String in your RestApi Interface like
Call<String> method(#Path(..)...);
And for that to work you would need to add the scalars converter factory to where you create your Retrofit object.
First you would need to import it:
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
And then add it:
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://your.base.url/")
.build();
And then in onResponse
public void onResponse(Call<String> call, Response<String> response) {
if (response.isSuccessful()) {
Type mapType = new TypeToken<Map<String,List<SomeClass>>() {}.getType(); // define generic type
Map<String,List<SomeClass>> result= gson.fromJson(response.body(), mapType);
} else {
}
}
Also,check out this site it has great tutorials on Retrofit.
I am trying to consume a JSON using retrofit2 and GSON.
The following is the response provided by the server. Note that the value of "d" is a string of a valid JSON (once the slashes are removed).
{"d": "[{\"Number\":\"2121\",\"NumberOfAppearances\":2,\"Prizes\":
[{\"DrawDate\":\"\/Date(1439654400000)\/\",\"PrizeCode\":\"S\"},
{\"DrawDate\":\"\/Date(874771200000)\/\",\"PrizeCode\":\"S\"}]}]"}
Is there a way to use retrofit2 to preparse the the json during the call to retrofitService to get the objects inside the value of d?
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
//is there anything i can do here to do preparsing of the results?
.addConverterFactory(GsonConverterFactory.create())
.build();
IQueryLocations = retrofit.create(IMyQuery.class);
//currently GsonResults is the string value of d, instead of the JSON objects
Call<GsonResult> result = IMyQuery.doQuery("2121");
Ideally, I like to insert a method call before addConverterFactory to do the preparsing
the output of the preparsing method would be some thing like the following:
{"d": [{"Number":"2121","NumberOfAppearances":2,"Prizes":
[{"DrawDate": 1439654400000,"PrizeCode":"S"},
{"DrawDate": 874771200000,"PrizeCode":"S"}]}]}
It's not your ideal solution, but you can return a wrapper for the result data:
class WrappedGsonResult {
private static final Gson GSON = new Gson();
#SerializedName("d")
private String data;
GsonResult() {}
public GsonResult getData() {
return GSON.fromJson(this.data, GsonResult.class);
}
}
Then:
Call<WrappedGsonResult> result = IMyQuery.doQuery("2121");
result.enqueue(new Callback() {
#Override
public void onResponse(final Call<WrappedGsonResult> call, final Response<WrappedGsonResult> response) {
if (response.isSuccessful()) {
GsonResult result = response.body().getData();
// ...
} else {
// ...
}
}
// ...
});
To exclude double quotes, you need to use excludeFieldsWithoutExposeAnnotation() provided by GsonBuilder.
For example:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
// Add Gson object
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Hope this helps.