Retrofit 2 returns HTML instead of JSON - java

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
}

Related

Android - Display loading bar when calling API with retrofit

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

How to convert BEGIN_OBJECT to BEGIN_ARRAY

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();
}
});

Proxy Authentication Required, Retrofit

Getting this error when make api call in retrofit
Response{protocol=http/1.1, code=407, message=Proxy Authentication
Required, url=http://example.com/test.xml}
below was my api call.
private void showProxies() {
serviceCall = apiService.listOfServers();
serviceCall.enqueue(new Callback<ServerListModel>() {
#Override
public void onResponse(Call<ServerListModel> call, Response<ServerListModel> response) {
if (response.body() != null) {
ArrayList<Proxies> proxyArrayList = response.body().proxiesArrayList;
showProxyDialog(proxyArrayList);
}
else
Toast.makeText(BrowserActivity.this, "Server 407 error.", Toast.LENGTH_SHORT).show();
}
#SuppressLint("LongLogTag")
#Override
public void onFailure(Call<ServerListModel> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
you have add proxy to you Retrofit object
java.net.Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));
OkHttpClient client = new OkHttpClient.Builder().proxy(proxy).build();
Retrofit.Builder builder = new Retrofit.Builder().client(client);
Retrofit retrofit = builder.build();
In my case, I was connected to the proxy network this issue is not related to retrofit.

How can i post data with utf8 from Android to server

I want POST data from android to server, my server language is PHP.
When POST data, this data save with strange characters , such as this : وب تیحی . this data is utf8 characters and this data is not OK!. For requests i use Retrofit2
My POST request is :
private void sendComment(String cmPostID, String name, String email, String content) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
OkHttpClient client = new OkHttpClient();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
Retrofit_ApiInterface requestInterface = retrofit.create(Retrofit_ApiInterface.class);
comment = new Comment();
comment.setComment_post_ID(cmPostID);
comment.setComment_author(name);
comment.setComment_author_email(email);
comment.setComment_content(content);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.COMMENT);
request.setComment(comment);
Call<ServerResponse> response = requestInterface.cmOperation(request);
response.enqueue(new Callback<ServerResponse>() {
#Override
public void onResponse(Call<ServerResponse> call, Response<ServerResponse> response) {
ServerResponse resp = response.body();
if (resp.getResult().equals(Constants.SUCCESS)) {
sendLoad.setVisibility(View.INVISIBLE);
TastyToast.makeText(context, StringEscapeUtils.unescapeHtml4(resp.getMessage()), TastyToast.LENGTH_LONG,
TastyToast.SUCCESS);
closeCommentDialog();
} else {
sendCommentImage.setVisibility(View.VISIBLE);
sendLoad.setVisibility(View.INVISIBLE);
TastyToast.makeText(context, StringEscapeUtils.unescapeHtml4(resp.getMessage()), TastyToast.LENGTH_LONG,
TastyToast.ERROR);
}
}
#Override
public void onFailure(Call<ServerResponse> call, Throwable t) {
sendLoad.setVisibility(View.INVISIBLE);
sendCommentImage.setVisibility(View.VISIBLE);
TastyToast.makeText(context, "Faild, send Again please", TastyToast.LENGTH_LONG, TastyToast.ERROR);
}
});
}
How can i fix this problem, and send data with UTF8 ?

retrofit 2.0 how to print the full json response?

I am moving from Volley to Retrofit currently version 2.0.
How to print the the full json response code ?
includes:
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
RestClient:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Gson gson = new GsonBuilder()
.setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ROOT)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
REST_CLIENT = retrofit.create(APIService.class);
APIService:
#GET("my/json")
Call<Model> getFeed();
In Activity - Calling API:
Call<Model> call = RestClient.get().getFeed();
call.enqueue(new Callback<Model>() {
#Override
public void onResponse(Response<Model> response, Retrofit retrofit) {
Log.w("2.0 getFeed > response.raw() => ", response.raw().toString());//DONT WORK
Log.w("2.0 getFeed > retrofit => ", retrofit.toString());//DONT WORK
Log.w("2.0 getFeed > body => ", response.body().toString()); //DONT WORK
Log.w("2.0 getFeed > getStatus => ", response.body().getStatus());
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
Log.e("2.0 getFeed > onFailure => ", t.toString());
}
});
To print the full response in json:
Log.w("2.0 getFeed > Full json res wrapped in gson => ",new Gson().toJson(response));
If you'd like to have pretty print feature, use:
Log.w("2.0 getFeed > Full json res wrapped in pretty printed gson => ",new GsonBuilder().setPrettyPrinting().create().toJson(response));
Note that this prints the deserialized data (not raw response as returned from server). To get the raw response, you may use one of these:
Use HttpLoggingInterceptor see: https://stackoverflow.com/a/33256827/2267723 or have your own version of interceptor
Use http debugging tools such Stetho. see: http://facebook.github.io/stetho/ or Charles Web Debugging Proxy. see: https://www.charlesproxy.com
Actually Square already create a class just for this, just add
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
And, in Retrofit
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("https://yourapi.com/api/")
.build();
The interceptor class is in maven central
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
You can set the logging level in HttpLoggingInterceptor class. BODY is the verbose one (it print everything to the Body). Further information is available on OkHttp github
Caution!
Don't forget to remove Interceptors (or change Logging Level to NONE) in production! Otherwise people will be able to see your request and response on Log Cat.
Plug in the following interceptor class like this
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());
//////Interceptor class
public static class LoggingInterceptor implements Interceptor {
#Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Log.i("LoggingInterceptor","inside intercept callback");
Request request = chain.request();
long t1 = System.nanoTime();
String requestLog = String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers());
if(request.method().compareToIgnoreCase("post")==0){
requestLog ="\n"+requestLog+"\n"+bodyToString(request);
}
Log.d("TAG","request"+"\n"+requestLog);
com.squareup.okhttp.Response response = chain.proceed(request);
long t2 = System.nanoTime();
String responseLog = String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
String bodyString = response.body().string();
Log.d("TAG","response only"+"\n"+bodyString);
Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
}
public static String bodyToString(final Request request) {
try {
final Request copy = request.newBuilder().build();
final Buffer buffer = new Buffer();
copy.body().writeTo(buffer);
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}`
Courtesy: https://github.com/square/retrofit/issues/1072#
To get full response in Json in retrofit use below.
this works for me.
call.enqueue(new Callback<someList>() {
#Override
public void onResponse(Call<someList> call, Response<someList> response) {
if (response.isSuccessful())
Log.e("Success", new Gson().toJson(response.body()));
else
Log.e("unSuccess", new Gson().toJson(response.errorBody()));
}
#Override
public void onFailure(Call<someList> call, Throwable t) {
Log.e("onFailure", t.toString());
}
});
You can setLogLevel to your Retrofit adapter like below, and see the response and other data such as header, response code vs.
setLogLevel(LogLevel.FULL)
If you're using Retrofit version 2+ you have to set OkHttpLoggingInterceptor to see logs.
First add OkHttpLoggingInterceptor to your project:
com.squareup.okhttp3:logging-interceptor:${Versions.okHttpLoggingInterceptorVersion}
And than create init your interceptor:
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
And finally add it to your OkHttpClient
with(OkHttpClient.Builder()) {
if (BuildConfig.DEBUG) addInterceptor(loggingInterceptor)
build()
}
Try this !!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
/** Handles Log */
retrofit.client().interceptors().add(new LoggingInterceptor());
mRestClient = retrofit.create(RestServices.class);
class LoggingInterceptor implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Logger.d(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Logger.d(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
final String responseString = new String(response.body().bytes());
Logger.d("Response: " + responseString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), responseString))
.build();
}
Check this Demo !!!
Log.e("TAG","2.0 getFeed > response.raw() => " + new Gson().toJson(response.body()));
public class HttpLoggingInterceptor {
HttpLoggingInterceptor provideHttpLoggingInterceptor(){
return new HttpLoggingInterceptor(message ->
Log.d("TAG", message)).setLevel(HttpLoggingInterceptor.Level.BODY);
}
}
public class OkHttpClient {
OkHttpClient provideOkHttpClient(#NonNull HttpLoggingInterceptor interceptor){
return new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
}
}
Try this :
Log.d("LOG","RESPONSE ==="+response.raw().toString());
Take a look on okhttp3.logging package, they already have HttpLoggingInterceptor that you can use for your needs.
And depending on them you can also specify logging level.
and you can include this interceptor to your request as mentioned - via OkHttpClient.Builder:
public OkHttpClient provideOkHttpClient() {
final OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
okHttpBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
return okHttpBuilder.build();
}
To get full json response with retrofit 2.0 follow code given below
Api Interface
#GET("my/json")
Call<JsonObject> getFeed();
Retrofit Call function
Call<JsonObject> call = RestClient.get().getFeed();
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Log.d("res", response.body().toString());
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d("error",t.getMessage());
}
});
Call<Model> call = RestClient.get().getFeed();call.enqueue(new Callbstrong
textack<Model>() {
#Override
public void onResponse(Response<Model> response, Retrofit retrofit) {
//try this
Call<Model> call = response.body();
// this is enough for retrieve model
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
og.e("2.0 getFeed > onFailure => ", t.toString());
}
});

Categories