Starting from the JSON
presented by you and the data structure also presented in the question, if we use a standard approach like this:
final Gson gson = new Gson();
final Response response = gson.fromJson(json, Response.class);
Or this:
final Gson gson = new Gson();
final Type type = new TypeToken<List<Post>>() {}.getType();
final List<Post> posts = gson.fromJson(json, type);
response.setMPosts(posts);
Won’t work.
In the first case an error will be displayed: Expected BEGIN_OBJECT but was BEGIN_ARRAY
, why, of course the JSON
does not start with an object but rather a vector; in the second, all attributes will be null or with their default value, because Gson does not support by default the nomenclature policy adopted in these objects.
There are some ways to do this and I will show you only one.
- use
@SerializedName
attributes with name outside the supported pattern;
- create a custom deserializer. See here how it works: writing an deserializer;
- use
FieldNamingStrategy
and define the nomenclature strategy used in its attributes, a DE-PARA
between attributes in java objects and attributes in JSON;
- rename the attributes of your objects to reflect some standard approach already supported by Gson. See this link:
FieldNamingPolicy
;
As you have not been quoted which approach you are already using to deserialize up to the list and Post
s, I will show as an example the third approach, creating an own nomenclature strategy.
I am only considering the attributes shown in the question, if there are others that do not follow the pattern you should consider in your implementation.
To have this own strategy we will implement the interface FieldNamingStrategy
, the implementation of the method #translate(Field)
will be more or less like this:
final String fieldName = f.getName();
if (fieldName.equalsIgnoreCase("mAnexos")) {
return "anexos";
}
final Class<?> declaringClass = f.getDeclaringClass();
final String className = declaringClass.getSimpleName().toLowerCase();
return className + "_" + fieldName.toLowerCase();
The attribute mAnexos
is the only one who does not share the same pattern as the other attributes, so if it is we will return attachments, the name of the attribute in JSON
. The others follow the same pattern, that is, the name of the class in which they are in low box separated by a _
of the attribute name.
You can implement the straterium in several ways, an example in Java 8 would be this:
final FieldNamingStrategy strategy = (final Field f) -> {
final String fieldName = f.getName();
if (fieldName.equalsIgnoreCase("mAnexos")) {
return "anexos";
}
final Class<?> declaringClass = f.getDeclaringClass();
final String className = declaringClass.getSimpleName().toLowerCase();
return className + "_" + fieldName.toLowerCase();
};
In other versions of Java you can implement this way (with anonymous class):
final FieldNamingStrategy strategy = new FieldNamingStrategy() {
public String translateName(final Field f) {
final String fieldName = f.getName();
if (fieldName.equalsIgnoreCase("mAnexos")) {
return "anexos";
}
final Class<?> declaringClass = f.getDeclaringClass();
final String className = declaringClass.getSimpleName().toLowerCase();
return className + "_" + fieldName.toLowerCase();
}
};
After implementing the naming strategy, we can use it this way:
final Gson gson = new GsonBuilder().setFieldNamingStrategy(strategy).create();
final Type type = new TypeToken<List<Post>>() {}.getType();
final List<Post> posts = gson.fromJson(json, type); // substitua "json" pelo o json que você precisa deserializar
final Response response = new Response();
response.setMPosts(posts);
You can also create another object that implements FieldNamingStrategy
, is at your discretion.
Edenilton, includes an answer to the question. You managed to solve?
– Bruno César
Due to the time factor, I was able to solve the problem, maybe it was not a "good practice" to use the conversions manually with objects of the Jsonobject and Jsonarray classes. My goal was to decrease as much as possible the lines of codes and speed up the process of deserialization. Thanks! Next times I will use them calmly. I had a problem when using "Field". I was not compiling. It asked me to change the project build settings: "Change project Compilance and JRE to 1.8.
– Edenilton Michael
If you have any project configured using json deserializers, please share it with me. thanks!
– Edenilton Michael
As for the error, it is because the code is in java 8 even, already includes a form with java before the 8 as well. The simplest way is to include the annotation
@SerializeName
in its same attributes, it is the one that demands the least code.– Bruno César