This is for all the JSON brains out there.
Let's say I have an interface like:
public interface Model {
String getName();
String getDateCreated();
String getTimeCreated();
String getLastUpdated();
String getLastUpdatedTime();
}
Then let's say I have an Item object:
public class Item {
private String name;
private Date created;
private Date updated;
..setters and getters
}
Then let's say I have an model wrapper:
public class ItemModel implements Model {
private final Item item;
public ItemModel(Item item){
this.item = item;
}
public String getName(){
return item.getName();
}
public String getDateCreated(){
Date created = item.getCreated();
//format the date nicely and return a date string
}
public String getTimeCreated(){
Date created = item.getCreated();
//format the date nicely and return a time string
}
...you get the gyst, right?
}
Question is:
- How do I serialize ItemModel so that the json output will reflect the getter names on the model interface?
- Specifically, which library does this most easily? How do you achieve this using a specific library?
- Finally, I DO NOT want to serialize the Item object wrapped inside the ItemModel
I want the output to be something like this:
{item : {name: '', dateCreated : '', timeCreated : '', lastUpdated : '', lastUpdatedTime : ''}
Thanks in advance!
I thought I should share what I have been able to come with so far, and get your feedback. It's almost meeting my requirements, but I'm not sure if it's the right way:
I was pointed to genson by a user here, and I find it very interesting.
First I created a Serializer
public class ModelSerializer implements Serializer {
@Override
public void serialize(T target, ObjectWriter writer, Context cntxt) throws TransformationException, IOException {
writer.beginObject();
for (Method method : target.getClass().getMethods()) {
String methodName = method.getName();
if (methodName.startsWith("get")) {
int index = "get".length();
String valueName = Character.toLowerCase(methodName.charAt(index)) + method.getName().substring(index + 1);
try {
String valueString = (String) method.invoke(target, new Object[]{});
writer.writeName(valueName).writeValue(valueString);
} catch (IllegalArgumentException ex) {
Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
throw new TransformationException(ex.getMessage());
} catch (IllegalAccessException ex) {
Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
throw new TransformationException(ex.getMessage());
} catch (InvocationTargetException ex) {
Logger.getLogger(ModelSerializer.class.getName()).log(Level.SEVERE, null, ex);
throw new TransformationException(ex.getMessage());
}
}
}
writer.endObject();
}
}
Next, I created Genson and passed the Serializer
Genson genson = new Genson.Builder().withSerializer(new ModelSerializer(), Model.class).create();
Now when I pass the ViewModel, I get the fields formatted as I expected
Model viewModel = new ItemModel(domainModel); where domainModel is an instance of Item System.out.println(genson.serialize(viewModel));