Enayet Hossain
Enayet Hossain

Reputation: 317

Gson can not convert api response

I am just trying to show user data after hitting the API using Retrofit. my api response is:

{ 
   "password":"111222333",
   "name":"test name",
   "email":"[email protected]",
   "username":"test1",
   "customer_id":"201060",
   "phone":"0196789"
}

but unfortunately, I am getting

"Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $" error.

I am totally stuck to show my json response.

My User.java class:


    public class User {
      @SerializedName("name")
      @Expose
      private String name;
      @SerializedName("email")
      @Expose
      private String email;
      @SerializedName("username")
      @Expose
      private String username;
      @SerializedName("customer_id")
      @Expose
      private String customerId;
      @SerializedName("phone")
      @Expose
      private String phone;
      @SerializedName("password")
      @Expose
      private String password;
      public String getName() {
        return name;
      }
      public String getEmail() {
        return email;
      }
      public String getUsername() {
        return username;
      }
      public String getCustomerId() {
        return customerId;
      }
      public String getPhone() {
        return phone;
      }
      public String getPassword() {
        return password;
      }
    }

My Login class:


    Gson gson = new GsonBuilder().setLenient().create();
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://us-central1-gmx-notification.cloudfunctions.net/")
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();
            all_api = retrofit.create(allApi.class);
    private void getUserDetails(String userName,String passWord){
            Call<User> call = all_api.getUserDetails(userName,passWord);
            call.enqueue(new Callback<User>() {
                @Override
                public void onResponse(Call<User> call, Response<User> response) {
                    if(!response.isSuccessful()){
                        Log.d(response.body());
                    }
                    else{
                        User user = response.body();
                        String content = "";
                        content+= "Name: "+user.getName()+"\n";
                        content+= "Email: "+user.getEmail()+"\n";
                        content+= "Customer ID: "+user.getCustomerId()+"\n";
                        content+= "Phone: "+user.getPhone()+"\n";
                        Log.d(content);
                  }
    });
    }

and my retrofit api class:


    package com.material.components;
    import java.util.List;
    import retrofit2.Call;
    import retrofit2.http.GET;
    import retrofit2.http.Query;
    public interface allApi {
      @GET("login")
      Call <User> getUserDetails(
              @Query("email") String email,
              @Query("password") String password
      );
    }

Upvotes: 0

Views: 222

Answers (1)

Eugene Troyanskii
Eugene Troyanskii

Reputation: 892

When i hit you api https://us-central1-gmx-notification.cloudfunctions.net/[email protected]&password=12345678

I got this response

Error: could not handle the request

So as your error says you expected Object but got a string. So or an error on the backend side or the request is incorrect or you forgot to add something to the request(Header or something else...).

For sure problem not in your model just got not a model that you expect in the response. Add Interceptor in your OkHttpClient to see what you get to be sure.

You need add this dependency to gradle

implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'

And here is a code example your API that will printing all networking stuff in the log:

public class NetworkManager {

    private static RESTAuthService restAuthService;

    /*timeout values in seconds*/
    private static final int CONNECTION_TIMEOUT = 10;
    private static final int WRITE_TIMEOUT = 10;
    private static final int READ_TIMEOUT = 10;

    static RESTAuthService getRESTAuthService() {
        if (restAuthService == null) {
            synchronized (NetworkManager.class) {
                if (restAuthService == null) {

                    OkHttpClient client = new OkHttpClient.Builder()
                            .addInterceptor(new RESTInterceptor())
                            .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
                            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                            .build();

                    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(NetworkConfig.BASE_AUTH_URL)
                            .addConverterFactory(GsonConverterFactory.create())
                            .client(client)
                            .build();

                    restAuthService = retrofit.create(RESTAuthService.class);
                }
            }
        }
        return restAuthService;
    }

    private static class RESTInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            Buffer buffer = new Buffer();
            if (request.body() != null) {
                request.body().writeTo(buffer);
            }
            Log.d("HTTP Request", "Request to " + request.url().toString()
                    + "\n" + request.headers().toString()
                    + "\n" + buffer.readUtf8());
            long t1 = System.nanoTime();
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();

            String msg = response.body().string();
            msg = msg.replace("\r", ""); // Note: Messages with '\r' not displayed correctly in logcat

            Log.d("HTTP Response", String.format("Response from %s in %.1fms%n\n%s",
                    response.request().url().toString(), (t2 - t1) / 1e6d, msg));

            Log.d("HTTP Response", "Response code = " + response.code());

            return response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), msg))
                    .build();
        }
    }
    }

Your MyLogin class will be something like this:

public class MuLogin {
/*timeout values in seconds*/
    private static final int CONNECTION_TIMEOUT = 10;
    private static final int WRITE_TIMEOUT = 10;
    private static final int READ_TIMEOUT = 10;

    allApi = all_api;

    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new RESTInterceptor())
        .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
        .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
        .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
        .build();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://us-central1-gmx-notification.cloudfunctions.net/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    all_api =retrofit.create(allApi.class);

    public void getUserDetails(String userName, String passWord) {
        Call<User> call = all_api.getUserDetails(userName, passWord);
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                if (!response.isSuccessful()) {
                    Log.d(response.body());
                } else {
                    User user = response.body();
                    String content = "";
                    content += "Name: " + user.getName() + "\n";
                    content += "Email: " + user.getEmail() + "\n";
                    content += "Customer ID: " + user.getCustomerId() + "\n";
                    content += "Phone: " + user.getPhone() + "\n";
                    Log.d(content);
                }
            });
        }
    }
    private static class RESTInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            Buffer buffer = new Buffer();
            if (request.body() != null) {
                request.body().writeTo(buffer);
            }
            Log.d("HTTP Request", "Request to " + request.url().toString()
                    + "\n" + request.headers().toString()
                    + "\n" + buffer.readUtf8());
            long t1 = System.nanoTime();
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();

            String msg = response.body().string();
            msg = msg.replace("\r", ""); // Note: Messages with '\r' not displayed correctly in logcat

            Log.d("HTTP Response", String.format("Response from %s in %.1fms%n\n%s",
                    response.request().url().toString(), (t2 - t1) / 1e6d, msg));

            Log.d("HTTP Response", "Response code = " + response.code());

            return response.newBuilder()
                    .body(ResponseBody.create(response.body().contentType(), msg))
                    .build();
        }
    }
}

Upvotes: 2

Related Questions