I am trying to consume a GET API that expects in its query params list an array of strings.
I am using Retrofit for the task.
In the API interface, I have the following defined:
#GET("user/explore")
Observable<User> fetchUsers(#Query("who") String who,
#Query("category") ArrayList<String> categories);
I am using Timber for logging and in the console, I see the request is made like the following:
http://192.168.2.208:3000/api/v1/user/explore?who=SOME_USER&category=SOME_CATEGORY
The expected request should be made like the following:
http://192.168.2.208:3000/api/v1/user/explore?who=SOME_USER&category=[SOME_CATEGORY,SOME_CATEGORY1,SOME_CATEGORY2]
Why is retrofit behaving this way event though categories are of type string arraylist?
ArrayList<String> carArrList = new ArrayList<>();
carArrList.add("a");
carArrList.add("b");
carArrList.add("c");
String[] catArr = (String[]) carArrList.toArray(new String[carArrList.size()]);
String catStr = Arrays.toString(catArr);
catStr = catStr.replaceAll(" ", "");
Log.e("catStr", catStr);
Call<User> call = apiService.fetchUsers(catStr);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
}
#Override
public void onFailure(Call<User> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
#GET("list/")
Call<User> fetchUsers(#Query("category") String categories);
final request generated
list/?category=[a,b,c]
Related
I am required to fetch the response mentioned below from firebase by its url. Not by using DatabaseReference or DataSnapshot class. Just by firebase realtime database url.
{
"Emily Aries": "199",
"First Last": "2",
"J J": "194",
"John Deniel": "198",
"Sec User": "3"
}
Here the names and its values are dynamic.This are the values that firebase url returns from specific node named "users". I am required to store names in Names arraylist and ids in ids arraylist.
Here I am attaching the snap of my firebase node structure alongwith code so far I have tried to implement.
ApiInterface.java
#GET("group_chat/Demo Group_2-g/users")
Call<JSONObject> groupUsers();
Snippet from implementation in my main class.
private void getGroupUsersName() {
apiInterface = ApiClient.createService(ApiInterface.class);
Call<JSONObject> call = apiInterface.groupUsers();
call.enqueue(new Callback<JSONObject>() {
#Override
public void onResponse(Call<JSONObject> call, retrofit2.Response<JSONObject> response) {
}
#Override
public void onFailure(Call<JSONObject> call, Throwable t) {
}
});
}
Use
JsonObject
Class from Gson Lib Instead of
JSONObject
#GET("group_chat/Demo Group_2-g/users")
Call<JsonObject> groupUsers();
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
JsonObject jsonObject=response.body();
ArrayList<String> names=new ArrayList<>();
ArrayList<String> ids =new ArrayList<>();
for(Map.Entry<String,JsonElement> entry : jsonObject.entrySet()){
names.add(entry.getKey());
ids.add(jsonObject.get(entry.getKey()).getAsString());
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
}
});
hope it Works
i'm new to android and using retrofit for the first time.
i've implemented all the things but retrofit is giving null values of responses.
this is my sample request:
http://192.168.1.0/demo/kdemo//webservice/api.php?query=user.auttentication&user_name=admin&password=admin
for this I'm taking base url as :
BASE_URL="http://192.168.1.0/demo/kdemo//webservice/"
and End point in interface as :
#GET("api.php")
Call<UserAuthenticaiton> getUserAuthentication(#Query("user.auttentication")
String userAuttentication,
#Query("user_name") String
user_name,
#Query("password") String
password);
JSon viewer is giving values but retrofit is not..
This is Api call:
ApiInterface apiService= ApiClient.getClient().create(ApiInterface.class);
Call<UserAuthenticaiton> call=apiService.getUserAuthentication("user.auttentication","admin","admin");
call.enqueue(new Callback<UserAuthenticaiton>() {
#Override
public void onResponse(Call<UserAuthenticaiton> call, Response<UserAuthenticaiton> response) {
String id=response.body().getId();
String error=response.body().getError();
Toast.makeText(LoginActivity.this, "Id: "+id+" Error: "+error, Toast.LENGTH_SHORT).show();
Intent intentNew=new Intent(LoginActivity.this,MainActivity.class);
startActivity(intentNew);
}
#Override
public void onFailure(Call<UserAuthenticaiton> call, Throwable t) {
Toast.makeText(LoginActivity.this, "Failed to load", Toast.LENGTH_SHORT).show();
}
});
I need to obtain the "product" data. When I get the response.message () it returns "ok", but the data I look for is not.
the API url format is like this: http://webhose.io/productFilter?token=789536e4-000d-4a3a-a7ac-223634f596**&format=json&q=in_stock%3Atrue
my problem was '%3A'
in the code its necessary to use ':' instead of '%3A'
thanks for your help.
Products.java
interface Products {
#GET("{typefilter}")
Call<Result> getProducts(#Path("typefilter") String typefilter, #Query("token") String token,
#Query("format") String format, #Query("q") String filter);
}
Activity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Service.Products service = Client.getClient().create(Service.Products.class);
Call<Result> call = service.getProducts("productFilter",
"789536e4-000d-4a3a-a7ac-223634f596**","json","in_stock%3Atrue");
call.enqueue(new Callback<Result>() {
#Override
public void onResponse(Call<Result> call, Response<Result> response) {
Result result = response.body();
Log.d("Result", response.message());
Log.d("Result", result.getNext());
Log.d("Result","quantity:" +result.getProducts().length);
}
#Override
public void onFailure(Call<Result> call, Throwable t) {
}
});
}
Use this interceptor to log request & response
Retrofit debugging with Okhttp logging interceptor
I would like to handle my response from server , but I don't know how JSON (from server) its looks like. So I tried to display response as String , but I cant do it. Is it possible to display response as String? And then handle the response correctly. thanks
(Retrofit 1.9)
LoginService loginService = RetrofitClient.createService(LoginService.class);
loginService.searchOffer(getToken(), offerSearch, new Callback<String>() {
#Override
public void success(String offerSearchRequestResource, Response response) {
String responseFromSercer = response.getBody();
}
#Override
public void failure(RetrofitError error) {
}
});
change your response model to
JSONObject (from Gson)
then in your
public void success(...){response.body.toString();}
like this:
Call<JsonObject> call = YOUR_API_INTERFACE().YOUR_METHOD(YOUR_PARAMS);
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, #NonNull Response<JsonObject> response) {
if(response.isSuccessful()) {
String responseFromSercer = response.body.toString();
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
.....
}
});
If you are sure the request runs successfully and there is a response back...use
System.out.println(response.getBody());
i'd also suggest you add Logging Interceptors here so that you can get a detailed view of all your API calls
i want to send string from app to server with retrofit 2, and get back return values. what is the problem?
but it doesn't work.
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RatingApiService retrofitService=retrofit.create(RatingApiService.class);
Call<String> call = retrofitService.registration("saeed","ali");
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
if(response!=null){
Log.i("upload","is success:" +response.body());
}else{
Log.i("upload","response is null");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.i("upload","onFailure: "+t.getMessage());
}
});
Interface:
public interface RatingApiService {
#FormUrlEncoded
#POST("android/add2/{email}{password}")
Call<String> registration(#Path("email") String email, #Path("password") String password);
}
Instead of using parameters to pass your data; put it in a req.body, then send it. By doing so, you can bypass the URL string limit and the code is much more organized.
public interface RatingApiService {
#Headers("Content-Type: application/json") //Must be set to application/json so req.body can be read.
#POST("android")
Call<String> registration(#Body UserRegistrationRequest body);
}
Now, you might ask what is the " UserRegistrationRequest" class? that will be the object class that will be sent as a JSON object. We define it by:
public class UserRegistrationRequest {
final String email;
final String password;
UserRegistrationRequest(String email, String password){
this.email = email;
this.password = password;
}
}
And then the final step. This is how you convert the object to a JSON object and send it to your server.
UserRegistrationRequest userRegistrationRequest = new UserRegistrationRequest(
RegisterNameFragment.sFirstName, RegisterNameFragment.sLastName, RegisterEmailFragment.sEmail,
RegisterPasswordFragment.sPassword, RegisterAgeFragment.sAge);
Call<Void> call = retrofit.insertUserRegistration(userRegistrationRequest);
call.enqueue(new Callback<UserRegistration>() {
#Override
public void onResponse(Call<UserRegistration> call, Response<UserRegistration> response) {
Log.d("blue", "Data is sent");
}
#Override
public void onFailure(Call<UserRegistration> call, Throwable t) {
Log.d("blue", "fail");
}
});
You need to add #Body annotation to your method like below.
#POST("users/new")
Call<User> createUser(#Body User user);
The content of #Body is sent to server as request body.
If you want to send email and password to server, you should create object that contains such data and use the object in the #Body annotation.