I just started with Retrofit 2 for Android, I opted for the good reviews I had, although I would have stayed with Volley since I see it much easier.
The fact is that the issue of deserializar the JSON with GSON is giving me quite the can.
I put the code so that it is understood:
I have created a Singleton to manage the connections of the whole app, I hope it's okay:
public class SingletonRetrofit {
public static final String BASE_URL = "xxxxxxxxxxxxxxxxxxx";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(User.class, new GenericDeserializer<User>())
.create();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
Then I created the following "generic" deserializer, and now I explain because I understand, but here I would like you to correct me if I'm wrong:
public class GenericDeserializer<T> implements JsonDeserializer<T>
{
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("type");
if(content.toString().equals("\"dbUserResponse\"")){
content = je.getAsJsonObject().get("user");
JsonObject jsonObject = content.getAsJsonObject();
if(jsonObject.has("nacimiento")){
String date = jsonObject.get("nacimiento").getAsString();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date2 = null;
try {
date2 = sdf.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
String newstring = new SimpleDateFormat("yyyy-MM-dd").format(date2);
jsonObject.addProperty("nacimiento", newstring);
content = jsonObject.getAsJsonObject();
}
}
}
if(content.toString().equals("\"dbAlertResponse\"")){
// other case..... etc...
}
else{
//content = '{"error":"mierror"}';
}
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
And now where I want to call my API:
//METODO CON RETROFIT
pDialog = new ProgressDialog(this);
pDialog.setMessage("Cargando...");
pDialog.show();
final String TAG = RegisterUser.class.getSimpleName();
ApiInterface apiService = SingletonRetrofit.getClient().create(ApiInterface.class);
Call<User> call = apiService.getUser(1);
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, retrofit2.Response<User> response) {
User userdatos = response.body();
if(userdatos != null){
((EditText) findViewById(R.id.email)).setText(userdatos.getEmail());
((EditText) findViewById(R.id.dateBirth)).setText(userdatos.getNacimiento().toString());
}
else{
//Toast.makeText(PersonalProfileActivity.this, "Error al cargar usuario", Toast.LENGTH_LONG).show();
}
pDialog.hide();
}
@Override
public void onFailure(Call<User>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, "error a la M");
Log.e(TAG, t.toString());
}
});
Well, I expose my problems:
1st - I can not format a date that arrives in the following JSON:
{
"type": "dbUserResponse",
"user": {
"email": "[email protected]",
"nacimiento": "1995-01-01T00:00:00+01:00",
}
}
All the answers of the calls come to me in this "style". That is, "type" indicates what type of response it is. For example in the case of "alerts" I would get "type": "dbAlertResponse".
For this reason I have created a generic deserializer, but I do not know if it is the right thing to do. In addition, as I say, it is impossible for the date format that is coming to me to be converted to the one I am interested in, which would be "yyyy-MM-dd".
2nd - I tried to add another deserializerTypeAdapter in the creation of the gson, but either I do not know how it is done, or it has not worked for me.
How would this situation be resolved correctly? thanks