android - implementar - Retrofit 2: Obtenga JSON del cuerpo de respuesta
retrofit tutorial android (10)
Descubrí que una combinación de las otras respuestas funciona:
interface ApiInterface {
@GET("/someurl")
Call<ResponseBody> getdata()
}
apiService.getdata().enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val rawJsonString = response.body()?.string()
}
})
La parte importante es que el tipo de respuesta debe ser
ResponseBody
y usar
response.body()?.string()
para obtener la cadena sin formato.
https://stackoverflow.com/a/33286112/860488
Quiero obtener la cadena json de mi api usando retrofit 2, no tengo ningún problema cuando uso retrofit 1 para obtener este json pero usar retrofit 2 devuelve nulo para mí.
Así es como se ve mi json
{"id":1,"Username":"admin","Level":"Administrator"}
Esta es mi API
@FormUrlEncoded
@POST("/api/level")
Call<ResponseBody> checkLevel(@Field("id") int id);
Así es como se ve mi código
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) {
}
});
Soy nuevo en la actualización 2 y uso el código anterior, siempre hace que mis aplicaciones se bloqueen porque
response.body().toString()
devuelve nulo.
Guíeme sobre cómo obtener esa cadena json para que pueda convertirla en JsonObject.
Entonces, aquí está el trato:
Cuando están haciendo
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Config.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Estás pasando GsonConverterFactory.create () aquí.
Si lo hace así, Gson convertirá automáticamente el objeto json que obtiene en respuesta a su objeto
<ResponseBody>
.
Aquí puede pasar todos los demás convertidores como Jackson, etc.
Puedes usarlo así.
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();
}
}
Si no tiene idea de cuál podría ser la respuesta de la API. Siga los pasos para convertir el valor de respuesta del cuerpo de respuesta en bytes e imprima en formato de cadena. Puede obtener la respuesta completa impresa en la consola.
Luego puede convertir cadenas a JSONObject fácilmente.
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))
}
})
Un mejor enfoque es dejar que Retrofit genere POJO para usted desde json (usando
gson
).
Lo primero es agregar
.addConverterFactory(GsonConverterFactory.create())
al crear su instancia de
Retrofit
.
Por ejemplo, si tenía una clase Java de
User
(como se muestra a continuación) que correspondía a su json, entonces su API de modificación podría devolver la
Call<User>
class User {
private String id;
private String Username;
private String Level;
...
}
agregar dependencia para 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''
crear clase para url base
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;
}
}
después de eso crear modelo de clase para obtener valor
public class ApprovalModel {
@SerializedName("key_parameter")
private String approvalName;
public String getApprovalName() {
return approvalName;
}
}
crear clase de interfaz
public interface ApiInterface {
@GET("append_url")
Call<CompanyDetailsResponse> getCompanyDetails();
}
después de eso en clase principal
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
}
usa esto para obtener String
String res = response.body().string();
en vez de
String res = response.body().toString();
y siempre mantenga un cheque de nulo antes de convertir el cuerpo de respuesta a cadena
if(response.body() != null){
//do your stuff
}
utilizar esta
response.body().get(0).getUsername().toString();
Si desea obtener una respuesta completa en formato JSON, intente esto:
He intentado una nueva forma de obtener una respuesta completa del servidor en formato JSON sin crear ninguna clase de modelo. No estoy usando ninguna clase de modelo para obtener datos del servidor porque no sé qué respuesta obtendré o puede cambiar según los requisitos.
Esta es la respuesta 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"
}
},
.
.
.
]}
-
En su interfaz API, cambie el parámetro
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); }
-
en su actividad principal donde está llamando a esto
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 } });
-
después de eso, normalmente puede obtener parámetros usando un objeto JSON y una matriz JSON
Use este link para convertir su JSON en POJO con opciones selectas como se selecciona en la imagen a continuación
Obtendrá una clase POJO por su respuesta como esta
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;
}
}
y usa una interfaz como esta:
@FormUrlEncoded
@POST("/api/level")
Call<Result> checkLevel(@Field("id") int id);
y llama así:
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(context,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) {
Toast.makeText(context,t.toString(),Toast.LENGTH_SHORT).show(); // ALL NETWORK ERROR HERE
}
});
y usar dependencias en Gradle
compile ''com.squareup.retrofit2:retrofit:2.3.0''
compile ''com.squareup.retrofit2:converter-gson:2.+''
NOTA:
El error se produce porque cambió su JSON a POJO (mediante el uso de
addConverterFactory(GsonConverterFactory.create())
en la
addConverterFactory(GsonConverterFactory.create())
).
Si desea una respuesta en JSON, elimine
addConverterFactory(GsonConverterFactory.create())
de Retrofit.
Si no, entonces use la solución anterior