Подтвердить что ты не робот

Модернизация 2: Получить JSON из тела ответа

Я хочу получить строку json из моего api, используя retrofit 2, у меня нет проблем при использовании retrofit 1, чтобы получить этот json, но с помощью retrofit 2 возвращает null для меня.

Это то, что мой json выглядит как

{"id":1,"Username":"admin","Level":"Administrator"}

Это мой API

@FormUrlEncoded
@POST("/api/level")
Call<ResponseBody> checkLevel(@Field("id") int id);

Вот как выглядит мой код

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Api api = retrofit.create(Api.class);
        Call<ResponseBody> call = api.checkLevel(1);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                JsonObject post = new JsonObject().get(response.body().toString()).getAsJsonObject();
                    if (post.get("Level").getAsString().contains("Administrator")) {

                    }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
            }
        });

Я новичок в retrofit 2 и, используя вышеприведенный код, он всегда приводит к сбою моих приложений, потому что response.body().toString() возвращает null.

Расскажите, как получить эту строку json, чтобы преобразовать ее в JsonObject.

4b9b3361

Ответ 1

Используйте эту ссылку, чтобы конвертировать JSON в POJO с опциями выбора, как показано на рисунке ниже

enter image description here

Вы получите класс POJO для вашего ответа, как это

public class Result {

    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("Username")
    @Expose
    private String username;
    @SerializedName("Level")
    @Expose
    private String level;

    /**
    * 
    * @return
    * The id
    */
    public Integer getId() {
        return id;
    }

    /**
    * 
    * @param id
    * The id
    */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
    * 
    * @return
    * The username
    */
    public String getUsername() {
        return username;
    }

    /**
    * 
    * @param username
    * The Username
    */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
    * 
    * @return
    * The level
    */
    public String getLevel() {
        return level;
    }

    /**
    * 
    * @param level
    * The Level
    */
    public void setLevel(String level) {
        this.level = level;
    }

}

и используйте интерфейс как это:

@FormUrlEncoded
@POST("/api/level")
Call<Result> checkLevel(@Field("id") int id);

и звоните так:

Call<Result> call = api.checkLevel(1);
call.enqueue(new Callback<Result>() {
    @Override
    public void onResponse(Call<Result> call, Response<Result> response) { 
     if(response.isSuccessful()){
        response.body(); // have your all data
        int id =response.body().getId();
        String userName = response.body().getUsername();
        String level = response.body().getLevel();
        }else   Toast.makeText(Login.this,response.errorBody().string(),Toast.LENGTH_SHORT).show(); // this will tell you why your api doesnt work most of time

    }

    @Override
    public void onFailure(Call<Result> call, Throwable t) {
    }
});

и использовать зависимости в градале

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.+'

ПРИМЕЧАНИЕ. Ошибка возникает из-за того, что вы изменили JSON на POJO (с помощью addConverterFactory(GsonConverterFactory.create()) в модификации). Если вы хотите получить ответ в JSON, удалите addConverterFactory(GsonConverterFactory.create()) из Retrofit. Если нет, то используйте вышеуказанное решение

Ответ 2

Если вы хотите получить полный ответ в формате JSON, попробуйте это:

Я попробовал новый способ получить полный ответ от сервера в формате JSON без создания какого-либо класса модели. Я не использую какой-либо класс модели для получения данных с сервера, потому что я не знаю, какой ответ я получу, или он может измениться в соответствии с требованиями.

это ответ JSON:

{"contacts": [
    {
        "id": "c200",
        "name": "sunil",
        "email": "[email protected]",
        "address": "xx-xx-xxxx,x - street, x - country",
        "gender" : "male",
        "phone": {
            "mobile": "+91 0000000000",
            "home": "00 000000",
            "office": "00 000000"
        }
    },
    {
        "id": "c201",
        "name": "Johnny Depp",
        "email": "[email protected]",
        "address": "xx-xx-xxxx,x - street, x - country",
        "gender" : "male",
        "phone": {
            "mobile": "+91 0000000000",
            "home": "00 000000",
            "office": "00 000000"
        }
    },
    .
    .
    .
]}
  1. В вашем интерфейсе API измените параметр

    public interface ApiInterface {
    @POST("/index.php/User/login")//your api link 
    @FormUrlEncoded
    Call<Object> getmovies(@Field("user_email_address") String title,
                    @Field("user_password") String body);
    }
    
  2. в вашей основной деятельности, где вы называете это

    ApiInterface apiService =
            ApiClient.getClient().create(ApiInterface.class);
    
    Call call = apiService.getmovies("[email protected]","123456");
    call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            Log.e("TAG", "response 33: "+new Gson().toJson(response.body()) );
        }
    
        @Override
        public void onFailure(Call call, Throwable t) {
            Log.e("TAG", "onFailure: "+t.toString() );
            // Log error here since request failed
        }
    });
    
  3. после этого вы обычно можете получить параметр, используя объект JSON и массив JSON

Выход enter image description here

Ответ 3

используйте это, чтобы получить строку

String res = response.body().string();

вместо

String res = response.body().toString();

и всегда проверяйте значение null перед преобразованием тела ответа в строку

if(response.body() != null){
     //do your stuff   
}

Ответ 4

добавить зависимость для retrofit2

compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

создать класс для базового URL

public class ApiClient     
{
public static final String BASE_URL = "base_url";

private static Retrofit retrofit = null;

public static Retrofit getClient() {
    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

}

после этого создайте модель класса, чтобы получить значение

public class ApprovalModel {

@SerializedName("key_parameter")
private String approvalName;
public String getApprovalName() {
    return approvalName;
}
}

создать класс интерфейса

public interface ApiInterface { 
@GET("append_url")
Call<CompanyDetailsResponse> getCompanyDetails();
}

после этого в основном классе

 if(Connectivity.isConnected(mContext)){
            final ProgressDialog mProgressDialog = new ProgressDialog(mContext);
            mProgressDialog.setIndeterminate(true);
            mProgressDialog.setMessage("Loading...");
            mProgressDialog.show();

            ApiInterface apiService =
                    ApiClient.getClient().create(ApiInterface.class);

            Call<CompanyDetailsResponse> call = apiService.getCompanyDetails();
            call.enqueue(new Callback<CompanyDetailsResponse>() {
                @Override
                public void onResponse(Call<CompanyDetailsResponse>call, Response<CompanyDetailsResponse> response) {
                    mProgressDialog.dismiss();
                    if(response!=null && response.isSuccessful()) {
                        List<CompanyDetails> companyList = response.body().getCompanyDetailsList();

                        if (companyList != null&&companyList.size()>0) {
                            for (int i = 0; i < companyList.size(); i++) {
                                Log.d(TAG, "" + companyList.get(i));
                            }
                         //get values
                        }else{
                            //show alert not get value
                        }
                    }else{
                        //show error message

                    }
                }

                @Override
                public void onFailure(Call<CompanyDetailsResponse>call, Throwable t) {
                    // Log error here since request failed
                    Log.e(TAG, t.toString());
                    mProgressDialog.dismiss();
                }
            });
        }else{
            //network error alert box

        }

Ответ 5

Лучший подход - позволить Retrofit генерировать POJO для вас из json (используя gson). Прежде всего, нужно добавить .addConverterFactory(GsonConverterFactory.create()) при создании экземпляра Retrofit. Например, если у вас был класс java User (такой как показано ниже), который соответствовал вашему json, тогда ваш api-версия api может вернуться Call<User>

class User {
    private String id;
    private String Username;
    private String Level;
    ...
}    

Ответ 6

Итак, вот сделка:

При создании

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

Вы передаете GsonConverterFactory.create() здесь. Если вы сделаете это так, Gson автоматически преобразует объект json, который вы получите в ответ на ваш объект <ResponseBody>. Здесь вы можете передать все другие конверторы, такие как Джексон и т.д.

Ответ 7

Если у вас нет идеи о том, что может быть ответом от API. Выполните шаги, чтобы преобразовать значение ответа responsebody в байты и распечатать в формате String. Весь ответ можно распечатать в консоли.

Затем вы можете легко преобразовать строку в JSONObject.

      apiService.getFeeds(headerMap, map).enqueue(object : Callback, retrofit2.Callback<ResponseBody> {
            override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
            }

            override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
                val bytes = (response!!.body()!!.bytes())
                Log.d("Retrofit Success : ", ""+ String(bytes))
            }
        })

Ответ 8

Вы можете использовать это так.

 public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
            if (response.isSuccessful()) {
                try {
                    JSONObject jsonObject = new JSONObject(new Gson().toJson(response.body()));
                    msg = jsonObject.getString("msg");
                    status = jsonObject.getBoolean("status");

                    msg = jsonObject.getString("msg");
                    status = jsonObject.getBoolean("status");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                Log.e("cvbnop",response.body().toString());
            } else {
                Toast.makeText(MainActivity.this, "Some error occurred...", Toast.LENGTH_LONG).show();
            }
        }

Ответ 9

Я обнаружил, что комбинация других ответов работает:

interface ApiInterface {
    @GET("/someurl")
    Call<ResponseBody> getdata()
}

apiService.getdata().enqueue(object : Callback {
    override fun onResponse(call: Call, response: Response) {
        val rawJsonString = response.body()?.string()
    }
})

Важной частью является то, что тип ответа должен быть ResponseBody и использовать response.body()?.string() для получения необработанной строки.

fooobar.com/questions/189054/...

Ответ 10

используйте этот

response.body().get(0).getUsername().toString();