I am writing a custom Serializer (Jackson JSON) for List class, this list could be inferred with different class types, so I'll need to grab object fields values using reflection.
Note, all this classes has public values (no setters and getters), so Invoking the getter will not be an option.
This is what I get so far:
package com.xxx.commons.my.serializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.List;
public class ListSerializer extends StdSerializer<List> {
public ListSerializer() {
super(List.class);
}
@Override
public void serialize(List aList, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (aList != null) {
jsonGenerator.writeStartObject();
for (int index = 0 ; index < aList.size(); index++) {
try {
Object next = aList.get(index);
List<Field> fields = FieldUtils.getAllFieldsList(next.getClass());
Object object = next.getClass().newInstance();
for (int j = 0 ; j < fields.size(); j ++ ) {
jsonGenerator.writeObjectField(String.format("%s[%s]",fields.get(j).getName(),index) , object);
}
} catch (Exception e) {
e.printStackTrace();
}
}
jsonGenerator.writeEndObject();
}
}
}
MyTest
package com.xxx.commons.my.serializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
public class ListSerializerTest {
private ObjectMapper mapper = new ObjectMapper();
@Test
public void test() throws Exception {
SimpleModule module = new SimpleModule();
module.addSerializer(new ListSerializer());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(module);
MyTempClassParent parent = new MyTempClassParent();
parent.mylist.add(new MyTempClass("1","2","3"));
String json = mapper.writeValueAsString(parent);
System.out.println(json);
}
}
Example classes:
public class MyTempClass {
public MyTempClass() {
}
public MyTempClass(String value1, String value2, String value3) {
this.valueA = value1;
this.valueB = value2;
this.valueC = value3;
}
public String valueA;
public String valueB;
public String valueC;
}
public class MyTempClassParent {
public List<MyTempClass> mylist = new LinkedList<>();
}
Any ideas or alternatives for writing this ?