تغییر تبدیل دستی به اتوماتیک کلاس مربوط به Call در Retrofit

پرسیده شده
فعالیت 998 روز پیش
دیده شده 395 بار
0

با سلام و وقت بخیر

در حال نوشتن برنامه ای هستند که خصوصی است و اول افراد لاگین میکنند و بعد کالاها را می بینند.

قبلا با Velley اطلاعات به درستی دریافت میشد. الان پروژه را تبدیل به retrofit کردم تقریبا به همان روش.

 

(چون پاسخ json بازگشتی nested Class بود و به کمک GsonFactory به صورت اتوماتیک به کلاسها تبدیل نمیشد. به طور دستی اطلاعات را به کلاسها bind کردم)

 

برای گرفتن اطلاعات خوشبختانه توانستم اطلاعات را به صورت دستی به کلاس مربوطه تبدیل کنم.

 

به نظر شما چه کار کنم تا بتونم به صورت اتوماتیک json را تبدیل به کلاس کنم.

 

در حال حاضر اطلاعات گروه های کالا را  از سرور دریافت و به صورت دستی به کلاس RootCategory  تبدیل کردم. یعنی مقدار بازگشتی را یک JsonObject قرار دادم نه نام کلاس. سپس JsonObject  را به کلاس مربوطه تبدیل میکنم. و میتوان به درستی اطلاعات را دریافت کنم. 

  @POST("UserAccount/Login")
  Call<JsonObject> getUser(@Query("userID") String userID, @Query("password") String password);
  
  @POST("ProductCategory/Childs")
   Call<JsonObject>getCategories(@Query("Token") String Token);

 

 getUser هم به درستی کار میکند

در  getCategories هم اطلاعات به درستی دریافت میشود. 

 تنها تفاوت این است که در کلاس RootUser فقط یک آیتمهایش یک کاربر از کلاس User وجود دارد ولی در RootCategory  یکی از آیتم هایش یک لیست از کالاهاست. بقیه موارد دقیقا مشابه هستند.

 

با توجه به اینکه باید اطلاعات را دستی set میکردم کلاس RootUser  و RootCategory را از حالت abstract خارج کردم. و Constrauctor برایش ایجاد کردم.

 

.کدهای هر دو کلاس را مشاهده بفرمایید

public class RootCategory {

    @Expose
    @SerializedName("Data")
    private List<Category> categories;
    @Expose
    @SerializedName("Messages")
    private List<String> messages;
    @Expose
    @SerializedName("Success")
    private boolean success;

    public RootCategory() {
        this.categories = new ArrayList<>();
        this.messages = new ArrayList<>();
        this.success = false;
    }

    public List<Category> getCategories() {return categories; }

    public void setCategories(List<Category> categories) {this.categories = categories;  }

    public List<String> getMessages() { return messages;   }

    public void setMessages(List<String> messages) { this.messages = messages; }

    public boolean getSuccess() {return success;  }

    public void setSuccess(boolean success) { this.success = success; }

    public boolean isSuccess() { return success; }
}
public class RootUser {
    @Expose
    @SerializedName("Data")
    private User user =null;

    @Expose
    @SerializedName("Messages")
    private List<String> messages =null;

    @Expose
    @SerializedName("Success")
    private boolean success=false;

    public User getUser() {return user; }

    public void setUser(User user) { this.user = user; }

    public List<String> getMessages() {return messages;}

    public void setMessages(List<String> messages) {this.messages = messages; }

    public boolean isSuccess() {return success; }

    public void setSuccess(boolean success) { this.success = success;}
}

 

و به این روش دستی اطلاعات را به کلاس RootUser تبدیل کردم. و به درستی کار میکند. و درست callback میشود.

public void getUser(String userName, String password, ApiService.getUserCallback callback) {
        retrofitApiService.getUser(userName,password).enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                boolean success=false;
                JsonArray message=null;
                JsonArray data=null;
                try {
                    Log.i(TAG, "onResponse: body"+response.body().toString());
                    success = response.body().get("Success").getAsBoolean();
                    message=response.body().get("Messages").getAsJsonArray();
                    data = response.body().get("Data").getAsJsonArray();

                    Log.i(TAG, "onResponse: Message"+message);
                    Log.i(TAG, "onResponse: messege size="+message.size());
                    Log.i(TAG, "onResponse: data size="+data.size());

                    RootUser rootUser=new RootUser() ;
                    rootUser.setSuccess(success);
                    //--------------------------------------
                    List<String> msg=new ArrayList<>();
                    for (int i = 0; i <message.size() ; i++) {
                        Log.i(TAG, "onResponse: (message.get(i)"+message.get(i));
                        msg.add(message.get(i).getAsString());
                    }
                    rootUser.setMessages(msg);
                    //--------------------------------------
                    User user=null;
                    for (int i = 0; i < data.size() ; i++) {
                        JsonObject jsonObject = data.get(i).getAsJsonObject();
                        user=gson.fromJson(jsonObject.toString(),User.class);
                    }
                    rootUser.setUser(user);
                    callback.OnSuccess(rootUser);
                }
                catch (Exception e) {
                    e.printStackTrace();
                    Log.i(TAG, "onResponse: Exception is "+e.toString());
                    callback.OnError(e);
                }
            }

            @Override
            public void onFailure(Call<JsonObject> call, Throwable t) {
                Log.i(TAG, "onFailure: Exception is "+new Exception(t).toString());
                callback.OnError(new Exception(t));
            }
        });
 }

اینترفیس آن  برای callback بدین شکل است.

    public interface getUserCallback{
        void OnSuccess(RootUser user);
        void OnError(Exception error);
    } 

---------------------------------------------------------------------------------------

به طور مشابه به طور دستی اطلاعات را به RootCategory تبدیل کردم.


public void  getCategories(ApiService.getCategoriesCallback callback) {
        String token=new MyUserManager(context).getToken();
        retrofitApiService.getCategories(token).enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
                boolean success=false;
                JsonArray message=null;
                JsonArray data=null;
                try {
                    Log.i(TAG, "onResponse: body"+response.body().toString());
                    success = response.body().get("Success").getAsBoolean();
                    message=response.body().get("Messages").getAsJsonArray();
                    data = response.body().get("Data").getAsJsonArray();

                    Log.i(TAG, "onResponse: Message"+message);
                    Log.i(TAG, "onResponse: messege size="+message.size());
                    Log.i(TAG, "onResponse: data size="+data.size());
                    RootCategory rootCategory=new RootCategory() ;
                    rootCategory.setSuccess(success);
                    //--------------------------------------
                    List<String> msg=new ArrayList<>();
                    for (int i = 0; i <message.size() ; i++) {
                        Log.i(TAG, "onResponse: (message.get(i)"+message.get(i));
                        msg.add(message.get(i).getAsString());
                    }
                    rootCategory.setMessages(msg);
                    //--------------------------------------
                    List<Category> list=new ArrayList<>();
                    Category cat=null;
                    for (int i = 0; i < data.size() ; i++) {
                        JsonObject jsonObject = data.get(i).getAsJsonObject();
                        cat=gson.fromJson(jsonObject.toString(),Category.class);
                        list.add(cat);
                    }
                    rootCategory.setCategories(list);
                    callback.OnSuccess(rootCategory);
                }
                catch (Exception e) {
                    e.printStackTrace();
                    Log.i(TAG, "onResponse: Exception is "+e.toString());
                    callback.OnError(e);
                }
            }
            @Override
            public void onFailure(Call<JsonObject> call, Throwable t) {
                callback.OnError(new Exception(t));
            }
        });
    }

اینترفیس ها برای callback بدین شکل است.

public interface getCategoriesCallback{
        void OnSuccess(RootCategory rootCategory);
        void OnError(Exception error);
    }

 

از زمانی که برای خواندن این سوال گذاشتید بسیار سپاسگزارم.

 

فایل پیوست

2
حذف شده

سلام وقت بخیر

همانطور که در تاپیک قبلیتون گفتم کلاس ها abstract نباشن و نکته بعدی هم اینکه برای nested json ها یک کلاس جدا ساخته بشه و درون property مربوطه در کلاس parent قرار بگیره در اینصورت تبدیل باید بصورت خودکار توسط retrofit انجام بشه. به dependency و معرفی converter factory به retrofit هم دقت کنید که مشکلی نداشته باشه

فایل پیوست

میلاد عزیززاده گلنگشی

توسط

میلاد عزیززاده گلنگشی

19 مرداد 00

حذف شده
متشکر. بله abstract حذف کرده بودم وقتی کلاسها جدا شدند و مشکل حل شد. بسیار سپاسگزارم