Модернизация 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.
Ответы
Ответ 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"
}
},
.
.
.
]}
-
В вашем интерфейсе 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);
}
-
в вашей основной деятельности, где вы называете это
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
}
});
-
после этого вы обычно можете получить параметр, используя объект 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();