i'm beginner of java, and i need some help, I had see many posts about, but not work they issues
I had json object from url like that
{
'history':[{
'id':2,
'name':'irine'},
{
'id':3,
'name':'karine'
}]
}
but i need
[
{
'id':2,
'name':'irine'},
{
'id':3,
'name':'karine'}
]
my ApiClient.java
public class ApiClient {
public static final String BASE_URL = "http://192.168.150.100";
public static Retrofit retrofit;
public static Retrofit getApiClient(final String authToken){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request.Builder ongoing = chain.request().newBuilder();
ongoing.addHeader("Accept", "application/json;");
ongoing.addHeader("Authorization", authToken);
return chain.proceed(ongoing.build());
}
})//.addInterceptor(interceptor)
.build();
if (retrofit==null){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
getting response from url
call.enqueue(new Callback<List<Contact>>() {
#Override
public void onResponse(Call<List<Contact>> call, Response<List<Contact>> response) {
progressBar.setVisibility(View.GONE);
contacts=response.body();
if(contacts==null)
Snackbar.make(findViewById(R.id.lt_search), "Nothing found",Snackbar.LENGTH_LONG).show();
adapter = new Adapter(contacts, SearchActivity.this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<Contact>> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Log.d("GHaa ka sk aksjdk j", contacts.toString());
Toast.makeText(SearchActivity.this, "Error\n"+t.toString(), Toast.LENGTH_LONG).show();
}
});
how to convert object to array or clear word 'history' from object?
You have provided the wrong class for API response.You are getting the list object against a string key which might change(not known). So, you will have to use HashMap. The API response is in the form of HashMap<String,<List<Contact>>>. So in the code, you will have to use Callback<HashMap<String,List<Contact>>>() instead of Callback<List<Contact>>().
Then from the HashMap you can easily get the list using hashmap.get('key'). In your case, hashmap.get('history').
The right way to reselve this problem:
call.enqueue(new Callback<HashMap<String,List<Contact>>>() {
#Override
public void onResponse(Call<HashMap<String, List<Contact>>> call, Response<HashMap<String, List<Contact>>> response) {
HashMap<String, List<Contact>> history=response.body();
contacts= new ArrayList<>(history.get("hitory"));
Log.d(TAG, contacts.toString());
progressBar.setVisibility(View.GONE);
//contacts=response.toString();
Log.d(TAG,response.toString());
if(contacts==null)
Snackbar.make(findViewById(R.id.lt_search), "Nothing found",Snackbar.LENGTH_LONG).show();
adapter = new Adapter(contacts, SearchActivity.this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<HashMap<String, List<Contact>>> call, Throwable t) {
progressBar.setVisibility(View.GONE);
//Log.d("GHaa ka sk aksjdk j", contacts.toString());
Toast.makeText(SearchActivity.this, "Error\n"+t.toString(), Toast.LENGTH_LONG).show();
}
});
Related
In my app i am using retrofit 2 to retrieve data from a API. I have no problem about this. The problem is that i want to display a loading bar while this execution. The code is this
Call<MainInvestorProducts> call = apiInterface.getUseraccounts("Bearer "+bearerToken);
mkLoader.setVisibility(View.VISIBLE);
call.enqueue(new Callback<MainInvestorProducts>() {
#Override
public void onResponse(Call<MainInvestorProducts> call, Response<MainInvestorProducts> response) {
// If success response set the textViews
if (response.code() == 200) {
retrievedData = response.body();
//else display error message
}else if (response.code() == 401) {
Toasty.error(getApplicationContext(), getString(R.string.expired_token),Toasty.LENGTH_LONG).show();
finish();
}
}
#Override
public void onFailure(Call<MainInvestorProducts> call, Throwable t) {
}
});
mkLoader.setVisibility(View.GONE);
The problem is that mkloader is never show up.
My APIClient code
public class APIClient {
public static Retrofit retrofit = null;
public static Retrofit getClient(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
retrofit = new Retrofit.Builder()
.baseUrl("https://api-test01.moneyboxapp.com")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
return retrofit;
}
}
And this is an example of the Interface
#Headers({
"AppId: 3a97b932a9d449c981b595",
"Content-Type: application/json",
"appVersion: 5.10.0",
"apiVersion: 3.0.0"
})
#POST("/users/login")
Call<MainUserLogin> logInUser(#Body LoginBody loginBody);
Before calling the api you should start showing the loader (be sure that the api call is going to happen) and when once completed dismiss that
mkLoader.setVisibility(View.VISIBLE);
Call<MainInvestorProducts> call = apiInterface.getUseraccounts("Bearer "+bearerToken);
call.enqueue(new Callback<MainInvestorProducts>() {
#Override
public void onResponse(Call<MainInvestorProducts> call, Response<MainInvestorProducts> response) {
// If success response set the textViews
if (response.code() == 200) {
retrievedData = response.body();
//else display error message
}else if (response.code() == 401) {
Toasty.error(getApplicationContext(), getString(R.string.expired_token),Toasty.LENGTH_LONG).show();
finish();
}
}
#Override
public void onFailure(Call<MainInvestorProducts> call, Throwable t) {
mkLoader.setVisibility(View.GONE);
}
});
you just need to make the loader visibility to VISIBLE before calling the API and in case the api is succes or failure you set visibility to GONE
I need to send an array of Strings using a Retrofit call. To do that I decided to create an object like this one:
public class SendEmailsList {
ArrayList<String> emails;
public SendEmailsList(ArrayList<String> emails) {
this.emails = emails;
}
}
And my JSON String must be like this:
{
"emails": ["email#server.com","email1#server.com","email2#server.com"]
}
This is the POST method defined in my interface:
#POST("/v2/companies/{companyId}/invite")
Call<ArrayList<String>> inviteMembers(#Path("companyId") String companyId, #Body SendEmailsList emails);
And this is the method that makes the Retrofit call:
public void SendNetworkRequest() {
OkHttpClient.Builder okhttpBuilder = new OkHttpClient.Builder();
okhttpBuilder.addInterceptor(new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder newRequest = request.newBuilder().header("Authorization", "Bearer " + token);
return chain.proceed(newRequest.build());
}
});
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BuildConfig.ENDPOINT)
.client(okhttpBuilder.build())
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
CompanyService invite = retrofit.create(CompanyService.class);
Call<ArrayList<String>> call = invite.inviteMembers("5602eb7ce49c9cd70409f206", new SendEmailsList(invitedEmails));
call.enqueue(new Callback<ArrayList<String>>() {
#Override
public void onResponse(Call<ArrayList<String>> call, Response<ArrayList<String>> response) {
System.out.println("Internal Users: " + response.code());
}
#Override
public void onFailure(Call<ArrayList<String>> call, Throwable t) {
// Log error here since request failed
Log.e("Internal Users Activity", t.toString());
}
});
}
But I am getting this error:
12-21 14:36:49.953 27953-27953/com.construct.test E/Internal Users Activity: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
How can I figure out what is going on?
I am making a POST Request to an ASP.NET API using Retrofit 2, I am getting an HTML in response instead of JSON. If I change the target URL and call a different API and get JSON response
Here is my API interface
#POST("PosLogin")
Call<CinekinRequest> login();
Rest Manager
public static final String BASE_URL = "******************";
private API homeApi;
public API getAPi() {
if (homeApi == null) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging);
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient.build())
.build();
homeApi = retrofit.create(API.class);
}
return homeApi;
}
Executing my login()
public void login(final Context context, CinekinRequest login){
Log.e("login", "starting");
Call call = manager.getAPi().login( );
call.enqueue(new Callback<CinekinRequest>() {
#Override
public void onResponse(Call<CinekinRequest> call, Response<CinekinRequest> response) {
Toast.makeText(context, "Success " + response.message(), Toast.LENGTH_SHORT).show();
Log.e("res", "success");
}
public void onFailure(Call<CinekinRequest> call, Throwable t) {
Toast.makeText(context, "error: " + t.getMessage(), Toast.LENGTH_LONG).show();
Log.e("error", t.getMessage());
}
});
}
Please add statement below in retrofit onResponse
if (response.isSuccessful()) {
// Do something
} else {
// Do something
}
or if you want only accept response 200
if (response.code() == 200) {
// Do something
} else {
// do something
}
I am trying to get a list of subscribers from gitHub Api, for example, from the this link
https://api.github.com/repos/couchbaselabs/query/subscribers
i created the below interface to retrieve the list of subscribers, and i added the below code to make a Retrofit call to retrieve list of repositiories
for a selected user.
for example, in my App I have a RecyclerView, each item/element in it contains repository name, avatar and description.
what I am trying to do is when the user clicks item number 4 in the Recyclerview I should provide the user with the list of subscribers to this repository.
exactly as shown in the link
https://api.github.com/repos/couchbaselabs/query/subscribers
For this link, for example, I want to get a list of all subscribers. tha's how I coded the below posted interface. but when i run the code posted in the code section
below, i dont receive any thing.
please let me know how to get list of scubscribers given the above link
code
//to parse json data when an item is clicked
holder.mLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "CLICKED #Position: " + position);
Log.d(TAG, "subURL: " + items.get(position).getSubscribers_url());
OkHttpClient okHttpClient = RetrofitFactory.getOkHttpClient();
Retrofit retrofitRef = RetrofitFactory.getRetrofit(mCtx, okHttpClient);
SubscribersApiEndpointInterface service = RetrofitFactory.create2(retrofitRef, SubscribersApiEndpointInterface.class);
Call<List<Subscribers>> call = RetrofitFactory.getSubscribers(service, "subscribers");
RetrofitFactory.enque(mCtx, call, position);
}
});
interface:
public interface SubscribersApiEndpointInterface {
#GET("repos/{subscriber}/query/subscribers")
Call<List<Subscribers>> subscriberForName(#Path("subscriber") String subscriber);
}
retrofit class:
/** BASE_URL:https://api.github.com/ **/
public class RetrofitFactory {
private final static String TAG = RetrofitFactory.class.getSimpleName();
public static OkHttpClient getOkHttpClient() {
return new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("Accept", "Application/JSON").build();
return chain.proceed(request);
}
}).build();
}
public static Retrofit getRetrofit(Context ctx, OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl(ctx.getResources().getString(R.string.BASE_URL))
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static SubscribersApiEndpointInterface create2(Retrofit retrofitRef, Class<SubscribersApiEndpointInterface> subscribersApiEndpointInterfaceClass) {
return retrofitRef.create(subscribersApiEndpointInterfaceClass);
}
public static Call<List<Subscribers>> getSubscribers(SubscribersApiEndpointInterface service, String name) {
return service.subscriberForName(name);
}
public static void enque(final Context ctx, Call<List<Subscribers>> call, final int position) {
call.enqueue(new Callback<List<Subscribers>>() {
#Override
public void onResponse(Call<List<Subscribers>> call, retrofit2.Response<List<Subscribers>> response) {
if (response.isSuccessful()) {
List<Subscribers> result = response.body();
Log.d(TAG, "result.size: " + result.size());
List<Items> items = (List<Items>) result.get(position);
Log.d(TAG, "items.size: " + items.size());
}
}
#Override
public void onFailure(Call<List<Subscribers>> call, Throwable t) {
Log.d(TAG, "FAILED");
}
});
}
}
Can anyone please give me some example how we can use protobuf in retrofit - I tried but its failed with some error , let me give you a sample of my implementation on that.
I hope you guys will help me.
ApiInterface.java
public interface ApiInterface {
#GET
Call<CommonProto.Country> makeGetRequest(#Url String url);
}
ApiClient.java
public class ApiClient {
public static final String BASE_URL = "**************************";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(Proto3ConverterFactory.create())
.build();
}
return retrofit;
}
}
MainActivity.java
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<CommonProto.Country> call = apiService.makeGetRequest("Services/CountryServices/GetAllCountry");
call.enqueue(new Callback<CommonProto.Country>() {
#Override
public void onResponse(Call<CommonProto.Country> call, Response<CommonProto.Country> response) {
String bodyString = null;
try {
Log.e("RETROFIT ::::::: ", String.valueOf(response.body())+"TEST");
} catch (Exception e) {
Log.e("RETROFIT ERROR ::::::: ", e.getMessage()+"TEST");
e.printStackTrace();
}
}
#Override
public void onFailure(Call<CommonProto.Country> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
}
);
when i run this way i got the error
java.lang.RuntimeException: com.google.protobuf.InvalidProtocolBufferException: Protocol message tag had invalid wire type.
my Proto.java file and also have Proto.proto file both are here in this link,
https://drive.google.com/folderview?id=0B4loQuzINvHCRUlNbk5LUXE1NXM&usp=sharing
Please let me know how to do this GET Req and also I was Struggling with POST Req.
you can create interface like this
public interface LoginInterface {
#FormUrlEncoded
#POST("url goes here")
Call<LoginResponseData> getUserLoginDeatail(#FieldMap Map<String, String> fields);
}
make an instance of retro file and call interface method something like this
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("base url")
.build();
webApis = retrofit.create(WebApis.class);
Call<LoginResponseData> call = webApis.getCurrentRide(keyValue);
call.enqueue(new Callback<LoginResponseData>() {
#Override
public void onResponse(Call<LoginResponseData> call, Response<LoginResponseData> response) {
try {
} catch (Exception e) {
// customizedToast.showToast(context.getResources().getString(
// R.string.exception));
e.printStackTrace();
}
}
#Override
public void onFailure(Call<LoginResponseData> call, Throwable t) {
}
});
for protocol buffer you can find a reference here