کمک تبدیل اتوماتیک nested Api ها به کلاس و استفاده در retrofit

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

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

یک Nested Api دارم و در تبدیل داده های دریافتی مشکل دارم.

در کلید Data با توجه به درخواست کاربر یا اطلاعات کاربر یا کالاها و یا گروه ها قرار میگیره. در کد زیر اطلاعات کاربر برگشته.

اگر در Data چیزی قرار نگیره در Message یک لیست ی از پیام ها قرار میگیرید.

 

در ThePermisions هم لیستی از رشته ها قرار میگیره.

{
    "Success": true,
    "Messages": [],
    "Data": [
        {
            "Token": "72ff5024-ce79-42c4-866d-ab321f4df653",
            "FirstName": "رضا زارعی",
            "LastName": "",
            "UserID": null,
            "Password": null,
            "Name": "2",
            "ThePermisions": [],
            "DefaultLanguage": "fa-IR"
        }
    ]
}
{
    "Success": true,
    "Messages": [],
    "Data": [
        {
            "ID": "36",
            "Title": "آموزشی",
            "HasChild": false
        },
        {
            "ID": "35",
            "Title": "اسباب بازی",
            "HasChild": false
        },
        {
            "ID": "37",
            "Title": "لوازم اداری",
            "HasChild": false
        },
        {
            "ID": "38",
            "Title": "لوازم تولد",
            "HasChild": false
        },
        {
            "ID": "34",
            "Title": "نوشت افزار",
            "HasChild": false
        }
    ]
}
{
    "Success": true,
    "Messages": [],
    "Data": [
        {
            "Code": "90006",
            "Title": "اتود اونر جديد",
            "Price": "",
            "Description": "",
            "ID": 60,
            "BarCode": "880916621565388091662184498809166217282 8809166214595 ",
            "Qty": "23"
        },
        {
            "Code": "90008",
            "Title": "اتود اينوكس",
            "Price": "",
            "Description": "",
            "ID": 62,
            "BarCode": "6948684102105",
            "Qty": "0"
        },
        {
            "Code": "90020",
            "Title": "استامپ كورش",
            "Price": "",
            "Description": "",
            "ID": 74,
            "BarCode": null,
            "Qty": "0"
        },
        {
            "Code": "90022",
            "Title": "استامپ نانو",
            "Price": "",
            "Description": "",
            "ID": 76,
            "BarCode": "5206313524270",
            "Qty": "0"
        }    
   ]
}

 

با پلاگین DTO  (که یکی از دوستان معرفی کرد )کلاسهای RootUser , RootProducts , RootCaregories ایجاد کردم. 

تصاویر مربوط به Api ضمیمه شده است. (برای اینکه نوع Data در هر url متفاوت است یک بار user ، یک بار لیست کالاها و بار دیگر لیست گروه ها است. پس حین تبدیل از نوع nested Class گذاشتم )

البته در RootUser باید یه user باشه نه یک لیست از آن که فعلا من تغییرش ندادم  هر وقت یه کاربر را لازم داشته باشم از لیست ایندکس 0 را برمیدارم و مشکلی نیست.

package ir.kargar.kararmad2.Model;

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

import java.util.List;

public abstract class RootUser {

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

    public List<Data> getData() {
        return data;
    }

    public void setData(List<Data> data) {
        this.data = data;
    }

    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 static class Data {
        @Expose
        @SerializedName("DefaultLanguage")
        private String defaultlanguage;
        @Expose
        @SerializedName("ThePermisions")
        private List<String> thepermisions;
        @Expose
        @SerializedName("Name")
        private String name;
        @Expose
        @SerializedName("LastName")
        private String lastname;
        @Expose
        @SerializedName("FirstName")
        private String firstname;
        @Expose
        @SerializedName("Token")
        private String token;

        public String getDefaultlanguage() {
            return defaultlanguage;
        }

        public void setDefaultlanguage(String defaultlanguage) {
            this.defaultlanguage = defaultlanguage;
        }

        public List<String> getThepermisions() {
            return thepermisions;
        }

        public void setThepermisions(List<String> thepermisions) {
            this.thepermisions = thepermisions;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getLastname() {
            return lastname;
        }

        public void setLastname(String lastname) {
            this.lastname = lastname;
        }

        public String getFirstname() {
            return firstname;
        }

        public void setFirstname(String firstname) {
            this.firstname = firstname;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }
    }
}
package ir.kargar.kararmad2.Model;

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

import java.util.List;

public abstract class RootProducts {

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

    public List<Data> getData() {
        return data;
    }

    public void setData(List<Data> data) {
        this.data = data;
    }

    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 static class Data {
        @Expose
        @SerializedName("Qty")
        private String qty;
        @Expose
        @SerializedName("BarCode")
        private String barcode;
        @Expose
        @SerializedName("ID")
        private int id;
        @Expose
        @SerializedName("Description")
        private String description;
        @Expose
        @SerializedName("Price")
        private String price;
        @Expose
        @SerializedName("Title")
        private String title;
        @Expose
        @SerializedName("Code")
        private String code;

        public String getQty() {
            return qty;
        }

        public void setQty(String qty) {
            this.qty = qty;
        }

        public String getBarcode() {
            return barcode;
        }

        public void setBarcode(String barcode) {
            this.barcode = barcode;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getPrice() {
            return price;
        }

        public void setPrice(String price) {
            this.price = price;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }
    }
}
package ir.kargar.kararmad2.Model;

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

import java.util.List;

public abstract class RootCategory {

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

    public List<Data> getData() {
        return data;
    }

    public void setData(List<Data> data) {
        this.data = data;
    }

    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 static class Data {
        @Expose
        @SerializedName("HasChild")
        private boolean haschild;
        @Expose
        @SerializedName("Title")
        private String title;
        @Expose
        @SerializedName("ID")
        private String id;

        public boolean getHaschild() {
            return haschild;
        }

        public void setHaschild(boolean haschild) {
            this.haschild = haschild;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }
    }
}

حال متدهای ایترفیس RetrofitApiService پاسخ های بازگشتی را باید به این کلاسها تبدیل کنند.

package ir.kargar.kararmad2;

import com.google.gson.JsonObject;

import ir.kargar.kararmad2.Model.RootCategory;
import ir.kargar.kararmad2.Model.RootProducts;
import ir.kargar.kararmad2.Model.RootUser;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

public interface RetrofitApiService {
    @POST("UserAccount/Login")
    Call<RootUser> getUser(@Body JsonObject body);

    @POST("Product/Products")
    Call<RootProducts>getProducts(@Body JsonObject body);

    @POST("ProductCategory/Childs")
    Call<RootCategory>getCategories(@Body JsonObject body);
}

حال در کلاس ApiService  باید نمونه ای از Retrofit و retrofitApiService را ایجاد کردم.

 

باید پارامترهای userID  ,  password را به کمک post ارسال کنم بنابراین در بدنه این را قرار دادم

package ir.kargar.kararmad2;

import android.content.Context;
import android.util.Log;

package ir.kargar.kararmad2;

import android.content.Context;
import android.util.Log;

import com.google.gson.JsonObject;

import ir.kargar.kararmad2.Model.RootCategory;
import ir.kargar.kararmad2.Model.RootProducts;
import ir.kargar.kararmad2.Model.RootUser;
import ir.kargar.kararmad2.setting.MyUserManager;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiService {
    private Context context;
    private String TAG;
    private String baseUrl;
    RetrofitApiService retrofitApiService;
    ApiService(Context context, String TAG){
        this.context=context.getApplicationContext();
        baseUrl=new MyUserManager(this.context).getBaseUrl();
        this.TAG=TAG;

        Retrofit retrofit=new Retrofit.Builder()
//                .addConverterFactory(JacksonConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(baseUrl)
                .build();

        retrofitApiService=retrofit.create(RetrofitApiService.class);
    }
    //---------------------------------------------------------------------------------------------
    public void getUser(String userName, String password, ApiService.getUserCallback callback) {
        JsonObject body=new JsonObject();
        body.addProperty("userID",userName);
        body.addProperty("password",password);

        retrofitApiService.getUser(body).enqueue(new Callback<RootUser>() {
            @Override
            public void onResponse(Call<RootUser> call, Response<RootUser> response) {
                Log.i(TAG, "onResponse: getuser");
                callback.OnSuccess(response.body());
            }

            @Override
            public void onFailure(Call<RootUser> call, Throwable t) {
                callback.OnError(new Exception(t));
            }
        });
    }
    public interface getUserCallback{
        void OnSuccess(RootUser user);
        void OnError(Exception error);
    }
//---------------------------------------------------------------------------------------------
    public void getProducts(int countProducts, ApiService.getProductCallback callback){
        JsonObject body=new JsonObject();
        body.addProperty("Token",new MyUserManager(context).getToken());
        retrofitApiService.getProducts(body).enqueue(new Callback<RootProducts>() {
            @Override
            public void onResponse(Call<RootProducts> call, Response<RootProducts> response) {

            }

            @Override
            public void onFailure(Call<RootProducts> call, Throwable t) {

            }
        });

    }
    interface getProductCallback{
        void OnSuccess(RootProducts productsList );
        void onError(Exception error);
    }
    //---------------------------------------------------------------------------------------------
    public void  getCategories(ApiService.getCategoriesCallback callback) {
        JsonObject body=new JsonObject();
        body.addProperty("Token",new MyUserManager(context).getToken());
        retrofitApiService.getCategories(body).enqueue(new Callback<RootCategory>() {
            @Override
            public void onResponse(Call<RootCategory> call, Response<RootCategory> response) {

            }

            @Override
            public void onFailure(Call<RootCategory> call, Throwable t) {

            }
        });
    }
    interface getCategoriesCallback{
        void OnSuccess(RootCategory categoriesList);
        void onError(Exception error);
    }
    //---------------------------------------------------------------------------------------------
    public void cancel(String TAG){
//        if (requestQueue != null)
//            requestQueue.cancelAll(TAG);
    }
}

حتی اگر کد callback را هم کامنت کنم خطای زیر را میده.

 OnSuccess:  error is java.lang.Exception: java.lang.RuntimeException: Failed to invoke public ir.kargar.kararmad2.Model.RootUser() with no args

 

در اکتیوتی Login  هم نوشتم

public  void getUser(){
        apiService=new ApiService(this,TAG);
        apiService.getUser(userName, password, new ApiService.getUserCallback() {
           @Override
           public void OnSuccess(RootUser rootuser) {
               RootUser.Data user =rootuser.getData().get(0);
               if(user !=null){
                   //ToDO change input after find ThePermition type
                   myUserManager.saveUserInfo(
                           user.getToken(),
                           user.getFirstname(),
                           user.getLastname(),
                           userName,
                           password,
                           user.getName());
                   myUserManager.setRememberInfo(rememberMeCHBOX.isChecked());
                   goToMainActivity();
               }
               else{
                   String message=rootuser.getMessages().get(0);
                   Log.i(TAG, "OnSuccess:  error is "+message);
                   showToast(message);
               }
           }

           @Override
           public void OnError(Exception error) {
               showToast(error.toString());
               Log.i(TAG, "OnSuccess:  error is "+error.toString());
           }
       });

    }

ا

لبته حتی کلاسها را به کمک Jackson هم سعی کردم بخوانم و برای retrofit هم addConverterFactory را JacksonConverterFactory  قرار دادم ولی باز هم در ارسال پارامتر با مشکل مواجه شدم.

 

یک سوال اساسی دیگه برای ارسال پارامتر از چه anotation ای باید استفاده کرد . من @Body استفاده کردم که به نظرم اشتباهه.

 

واقعا به کمک احتیاج دارم. باید از retrofit استفاده کنم و نمیتونم با nested API ها کار کنم. خواهشا اگر آموش مناسبی در اختیار دارید معرفی نمایید.

 

سپاس از وقت که گذاشتید.

 

فایل پیوست
retrofit Json.zip
479.32 KB