onResponse () Retrofit2 работает неправильно - PullRequest
0 голосов
/ 26 августа 2018

Я пытаюсь получить данные с сервера. Я написал модель сети, но некоторые ребята посоветовали использовать http://www.jsonschema2pojo.org/ или http://pojo.sodhanalibrary.com/. Я использовал оба из них, но проблема не решена. У меня есть авторизация, где я могу получить токен для доступа к другим данным. Итак, после авторизации я перехожу в AddressActivity, где я должен получить пользовательские данные (имя, почтовый индекс и т. Д.), И эти данные должны появиться в моем окне просмотра активности. Но этого не происходит. Тем не менее, я получаю данные. Я проверял это на OkHttp. Проблема с внешним видом. Я помещаю сообщения Toast после каждого метода и оператора if & else , чтобы проверить, какая часть не работает. Итак, я выяснил проблему с onResponse (..) , потому что я получаю Log и мое сообщение Toast в onFailure (..) . Но если я не авторизуюсь и не пытаюсь получить адреса, остальная часть onResponse (..) работает.

IService.kt:

package com.example.ganz.afex.net

import com.example.ganz.afex.models.Address_Network_Model
import com.example.ganz.afex.net.pojo.me.ResponseMe
import com.example.ganz.afex.net.pojo.re_and_log.*
import com.example.ganz.afex.net.pojo.update_password.RequestUpdatePass
import com.example.ganz.afex.net.pojo.update_password.ResponseUpdatePassword
import com.example.ganz.afex.net.pojo.update_profile.RequestUpdateProfile
import com.example.ganz.afex.net.pojo.update_profile.ResponseUpdateProfile
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.PUT

interface IService {

    @POST("authorize")
    fun login(@Body login: RequestLogin): Call<ResponseLogin>

    @POST("accesstoken")
    fun getToken(@Body request: GetAccessTokenRequest): Call<GetAccessTokenResponse>

    @GET("me")
    fun getMe(): Call<ResponseMe>

    @GET("addresses/all")
    fun getAllAddresses(): Call<List<Address_Network_Model>>
}

Recyc_Adapter_Addresses

package com.example.ganz.afex.adapters;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.ganz.afex.R;
import com.example.ganz.afex.models.Address_Network_Model;

import java.util.ArrayList;
import java.util.List;


public class Recyc_Adapter_Addresses extends RecyclerView.Adapter<Recyc_Adapter_Addresses.MyViewHolder> {


    private Context mContext;
    private static final String TAG = Recyc_Adapter_Addresses.class.getSimpleName();
    private List<Address_Network_Model> mAddrNetwork;



    public Recyc_Adapter_Addresses(Context mContext, List<Address_Network_Model> mAddrNetwork) {
        this.mContext = mContext;
        this.mAddrNetwork = mAddrNetwork;
    }

    public Recyc_Adapter_Addresses() {
        mAddrNetwork = new ArrayList<>();
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view;
        LayoutInflater mInflater = LayoutInflater.from(mContext);
        view = mInflater.inflate(R.layout.cardview_addresses, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tv_cust_city_id.setText(mAddrNetwork.get(position).getCityId());
        holder.tv_cust_address.setText(mAddrNetwork.get(position).getAddress());
        holder.tv_cust_zipcode.setText(mAddrNetwork.get(position).getZipCode());
        holder.tv_cust_phone_1.setText(mAddrNetwork.get(position).getPhone());
        holder.tv_cust_phone_2.setText(mAddrNetwork.get(position).getPhone2());
        holder.tv_cust_map_lat.setText(mAddrNetwork.get(position).getMapLat());
        holder.tv_cust_map_lng.setText(mAddrNetwork.get(position).getMapLng());
    }

    @Override
    public int getItemCount() {
       return mAddrNetwork.size();
    }

    public void addAddress(Address_Network_Model addrNetwork) {
            Log.d(TAG, addrNetwork.getAddress());
            mAddrNetwork.add(addrNetwork);
            notifyDataSetChanged();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv_cust_city_id;
        TextView tv_cust_address;
        TextView tv_cust_zipcode;
        TextView tv_cust_phone_1;
        TextView tv_cust_phone_2;
        TextView tv_cust_map_lat;
        TextView tv_cust_map_lng;

        public MyViewHolder(View itemView) {
            super(itemView);

            tv_cust_city_id = itemView.findViewById(R.id.tv_customer_city_id);
            tv_cust_address = itemView.findViewById(R.id.tv_customer_address);
            tv_cust_zipcode = itemView.findViewById(R.id.tv_customer_zipcode);
            tv_cust_phone_1 = itemView.findViewById(R.id.tv_customer_phone);
            tv_cust_phone_2 = itemView.findViewById(R.id.tv_customer_phone2);
            tv_cust_map_lat = itemView.findViewById(R.id.tv_customer_map_lat);
            tv_cust_map_lng = itemView.findViewById(R.id.tv_customer_map_lng);
        }
    }
}

Address_Network_Model:

        package com.example.ganz.afex.models;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Address_Network_Model {

    @SerializedName("city_id")
    @Expose
    private Integer cityId;
    @SerializedName("address")
    @Expose
    private String address;
    @SerializedName("zip_code")
    @Expose
    private String zipCode;
    @SerializedName("phone")
    @Expose
    private String phone;
    @SerializedName("phone2")
    @Expose
    private String phone2;
    @SerializedName("map_lat")
    @Expose
    private Integer mapLat;
    @SerializedName("map_lng")
    @Expose
    private Integer mapLng;

    public Integer getCityId() {
        return cityId;
    }

    public void setCityId(Integer cityId) {
        this.cityId = cityId;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPhone2() {
        return phone2;
    }

    public void setPhone2(String phone2) {
        this.phone2 = phone2;
    }

    public Integer getMapLat() {
        return mapLat;
    }

    public void setMapLat(Integer mapLat) {
        this.mapLat = mapLat;
    }

    public Integer getMapLng() {
        return mapLng;
    }

    public void setMapLng(Integer mapLng) {
        this.mapLng = mapLng;
    }
}

AddressActivity:

package com.example.ganz.afex.activities;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.ganz.afex.R;
import com.example.ganz.afex.adapters.Recyc_Adapter_Addresses;
import com.example.ganz.afex.models.Address_Network_Model;
import com.example.ganz.afex.net.NetworkManager;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static android.util.Config.LOGD;

public class AddressActivity extends AppCompatActivity  {

    private List<Address_Network_Model> addressList;
    private Recyc_Adapter_Addresses myAdapterAddress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_address);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        NetworkManager mNetworkManager = new NetworkManager(this);

       // if (mNetworkManager != null) {

            Toast.makeText(AddressActivity.this, "I guess NetworkManager is Not Null..", Toast.LENGTH_SHORT).show();


            Call<List<Address_Network_Model>> listCall = mNetworkManager.getService().getAllAddresses();

            listCall.enqueue(new Callback<List<Address_Network_Model>>()

            {
                @Override
                public void onResponse(Call<List<Address_Network_Model>> call,
                                       Response<List<Address_Network_Model>> response) {
                    Toast.makeText(AddressActivity.this, "I guess onResponce is working..", Toast.LENGTH_SHORT).show();
                    if (response.isSuccessful()) {
                        Toast.makeText(AddressActivity.this, "I guess IF STATEMENT is working..", Toast.LENGTH_SHORT).show();
                        addressList = response.body();

                        for (int i = 0; i < addressList.size(); i++) {
                            Address_Network_Model addrNetwork = addressList.get(i);
                            myAdapterAddress.addAddress(addrNetwork);
                            myAdapterAddress.notifyDataSetChanged();
                            Toast.makeText(AddressActivity.this, "I guess the circle is working..", Toast.LENGTH_SHORT).show();
                        }

                    } else {
                        Toast.makeText(AddressActivity.this, "I guess the circle is NOT working..1", Toast.LENGTH_SHORT).show();
                        int sc = response.code();
                        switch (sc) {

                        }
                        Toast.makeText(AddressActivity.this, "I guess the circle is NOT working..2", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onFailure(Call<List<Address_Network_Model>> call, Throwable t) {
                    Log.e("MyTag", "This is NOT running");
                    Toast.makeText(AddressActivity.this, "I guess here is Failure..", Toast.LENGTH_SHORT).show();
                }
            });
      /*  } else {
            Toast.makeText(AddressActivity.this, "Here is NullPointerException!", Toast.LENGTH_SHORT).show();
        }
        RecyclerView myRecyc_Addresses = findViewById(R.id.rv_customer_address);
        myAdapterAddress = new Recyc_Adapter_Addresses(this, new ArrayList<Address_Network_Model>());
        myRecyc_Addresses.setLayoutManager(new LinearLayoutManager(this));
        myRecyc_Addresses.setAdapter(myAdapterAddress);
    }

    public void gotoAddingAddress (View v) {
        Intent intentAddingAdd = new Intent (this, AddressAddingActivity.class);
        startActivity(intentAddingAdd);
        finish();
    }
}

NetworkManager:

package com.example.ganz.afex.net;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import com.example.ganz.afex.Config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.readystatesoftware.chuck.ChuckInterceptor;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class NetworkManager {
    private static NetworkManager instance = null;
    private IService service;
    private ConnectivityManager connectionService;

    public NetworkManager() {
    }

    public NetworkManager(final Context context) {
        connectionService = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        Interceptor interceptor = new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                SharedPreferences preferences = context.getSharedPreferences(Config.TOKEN, Context.MODE_PRIVATE);
                String value = preferences.getString(Config.TOKEN, "");
                Request newRequest = chain.request().newBuilder().addHeader(Config.HEADER_KEY, value).addHeader("Content-Type", "application/json").build();
                return chain.proceed(newRequest);
            }
        };

        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
                .create();
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .addInterceptor(logging)
                .addInterceptor(new ChuckInterceptor(context))
                .addInterceptor(interceptor)
                .build();
        Retrofit retrofit = new Retrofit.Builder()
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl("http://api.site.com/v1/")
                .build();
        service = retrofit.create(IService.class);

    }

    public static NetworkManager getInstance(Context context) {
        if (instance == null) {
            instance = new NetworkManager(context);
        }
        return instance;
    }

    public boolean isOnline() {
        NetworkInfo info = connectionService.getActiveNetworkInfo();
        return info != null;
    }

    public IService getService() {
        return service;
    }
}

UPDATE: Вход

Date: Mon, 27 Aug 2018 04:43:58 GMT
    Server: Apache/2.4.7 (Ubuntu)
    Set-Cookie: advanced-backend=e0c8fjbdmnh4fgt8r21jomvk99; path=/; HttpOnly
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate
    Pragma: no-cache
    X-Powered-By: Your Company <www.mywebsite.com>
    Access-Control-Allow-Origin: *
    Access-Control-Expose-Headers: 
    Set-Cookie: _identity-backend=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
    Set-Cookie: _csrf=X7bdxzchUN3XG4UWYEIdTx7931_y_TL_; path=/; HttpOnly
08-27 09:44:03.985 6259-6850/com.example.ganz.afex_with_default_navigation D/OkHttp: Content-Length: 552
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: application/json; charset=UTF-8
08-27 09:44:03.990 6259-6850/com.example.ganz.afex_with_default_navigation D/OkHttp: {
        "status": 1,
        "data": [
            {
                "city_id": 1,
                "address": "some address",
                "zip_code": "zip_code",
                "phone": "99891981651",
                "phone2": "99866518413",
                "map_lat": 654654,
                "map_lng": 65465500
            },
            {
                "city_id": 2,
                "address": "some address2",
                "zip_code": "zip_code2",
                "phone": "31213",
                "phone2": "321321",
                "map_lat": 32165500,
                "map_lng": 165850000000
            }
        ]
    }
    <-- END HTTP (552-byte body)
08-27 09:44:03.993 6259-6259/com.example.ganz.afex_with_default_navigation E/MyTag: This is NOT running
08-27 09:44:04.428 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@9529ad8[MainActivity]: Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=false 0} changed=false
08-27 09:44:05.758 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@691b290[Toast]: dispatchDetachedFromWindow
08-27 09:44:05.759 6259-6259/com.example.ganz.afex_with_default_navigation D/InputEventReceiver: channel 'e2defff Toast (client)' ~ Disposing input event receiver.
    channel 'e2defff Toast (client)' ~NativeInputEventReceiver.
08-27 09:44:05.811 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@fbaf254[Toast]: setView = android.widget.LinearLayout{966f5fd V.E...... ......I. 0,0-0,0} TM=true MM=false
08-27 09:44:05.812 6259-6259/com.example.ganz.afex_with_default_navigation V/Toast: Text: J gu in android.widget.Toast$TN@e7802f2
08-27 09:44:05.816 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@fbaf254[Toast]: dispatchAttachedToWindow
08-27 09:44:05.841 6259-6259/com.example.ganz.afex_with_default_navigation V/Surface: sf_framedrop debug : 0x4f4c, game : false, logging : 0
08-27 09:44:05.842 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@fbaf254[Toast]: Relayout returned: old=[0,0][0,0] new=[166,1064][554,1152] result=0x7 surface={valid=true 3348453376} changed=true
08-27 09:44:05.849 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@fbaf254[Toast]: MSG_RESIZED_REPORT: frame=Rect(166, 1064 - 554, 1152) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
08-27 09:44:07.780 6259-6259/com.example.ganz.afex_with_default_navigation D/ViewRootImpl@fbaf254[Toast]: dispatchDetachedFromWindow
08-27 09:44:07.780 6259-6259/com.example.ganz.afex_with_default_navigation D/InputEventReceiver: channel '53bdff7 Toast (client)' ~ Disposing input event receiver.
    channel '53bdff7 Toast (client)' ~NativeInputEventReceiver.

ОБНОВЛЕНИЕ № 2: Новый журнал:

Date: Thu, 30 Aug 2018 13:03:27 GMT
          Server: Apache/2.4.7 (Ubuntu)
          Set-Cookie: advanced-backend=r2cg25r0sojqsiubadta7019gj; path=/; HttpOnly
          Expires: Thu, 19 Nov 1981 08:52:00 GMT
          Cache-Control: no-store, no-cache, must-revalidate
          Pragma: no-cache
          X-Powered-By: Your Company <www.mywebsite.com>
          Access-Control-Allow-Origin: *
          Access-Control-Expose-Headers: 
D/OkHttp: Set-Cookie: _identity-backend=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
          Set-Cookie: _csrf=FDDU3VHxYtx5PAbCLMwbyvAmYZpkE_9E; path=/; HttpOnly
          Content-Length: 35
          Keep-Alive: timeout=5, max=100
          Connection: Keep-Alive
          Content-Type: application/json; charset=UTF-8
D/OkHttp: {
              "status": 1,
              "data": []
          }
          <-- END HTTP (35-byte body)

1 Ответ

0 голосов
/ 28 августа 2018

Я думаю, что проблема в том, что ваше пижо не соответствует Json, который вы получаете.В этом вызове

@GET("addresses/all")
fun getAllAddresses(): Call<List<Address_Network_Model>>

Вы возвращаете список адресов, но Json отличается.Если вы хотите десериализовать данный Json, вам нужно создать еще одно pojo, которое включает статус (на самом деле необязательно) и список адресов.Что-то вроде:

data class ResponseAddresses(
        @SerializedName("data")
        @Expose
        val  data: List<Address_Network_Model>
 )

Как вы можете видеть, pojo должно соответствовать иерархии Json.Теперь просто измените ваш запрос на модернизацию:

@GET("addresses/all")
fun getAllAddresses(): Call<ResponseAddresses>

РЕДАКТИРОВАТЬ

После некоторых запросов в комментариях приведено более подробное объяснение.

В журналах указан json:

{
 "status": 1,
 "data": [
   {
     "city_id": 1,
     "address": "some address",
     "zip_code": "zip_code",
     "phone": "99891981651",
     "phone2": "99866518413",
     "map_lat": 654654,
     "map_lng": 65465500
   },
   ...
  ]
}

Этот json не является списком адресов.Это объект, содержащий 2 поля - status и data.status - это целое число, а data - список адресов, которые вас интересуют.

Самый простой способ получить это правильно, проанализировав, - это реплицировать структуру json с POJO и использовать ее.Теперь я знаю, когда я впервые использовал kotlin, но давайте использовать Java здесь.Я только пишу поля.

class ResponseAddresses {
    @SerializedName("data")
    @Expose
    private List<Address_Network_Model> data;
    // ...
}

(вы можете добавить поле статуса, но это не нужно, если вам нужны только адреса)

Так что жездесь по-другому?Теперь у вас есть объект, который имеет 1 поле - data - список адресов.Теперь это намного проще сопоставить с JSON, который вы получаете, и у модернизации нет проблем с этим.Единственное пропущенное изменение - это вызов на модернизацию, и, как я уже говорил выше, вам нужно изменить тип возврата на Call<ResponseAddresses>:

@GET("addresses/all")
fun getAllAddresses(): Call<ResponseAddresses>

Как вы получите список адресов?Хорошо, просто получите к нему обычный доступ в onResponse:

@Override
public void onResponse(Call<ResponseAddresses> call,                                     
                       Response<ResponseAddresses> response) {
   if (response.isSuccessful()) {
      addressList = response.body().getData();
      // ...
   }
}

Основное изменение заключается в том, что теперь вам нужно вызвать геттер - getData() в этом примере.

...