You can implement two steps processing as follows.
Firstly, you convert your bean instance to a JsonNode instance using ObjectMapper. This guaranties applying all the Jackson annotations and customization. Secondly, you manually map the JsonNode fields to your "property-object" model.
Here is an example:
public class JacksonSerializer {
public static class Contact {
final public String email;
final public String firstname;
@JsonIgnore
public String ignoreMe = "abc";
public Contact(String email, String firstname) {
this.email = email;
this.firstname = firstname;
}
}
public static class Property {
final public String property;
final public Object value;
public Property(String property, Object value) {
this.property = property;
this.value = value;
}
}
public static class Container {
final public List<Property> properties;
public Container(List<Property> properties) {
this.properties = properties;
}
}
public static void main(String[] args) throws JsonProcessingException {
Contact contact = new Contact("abc@gmail.com", "John");
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(contact, JsonNode.class);
Iterator<String> fieldNames = node.fieldNames();
List<Property> list = new ArrayList<>();
while (fieldNames.hasNext()) {
String fieldName = fieldNames.next();
list.add(new Property(fieldName, node.get(fieldName)));
}
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new Container(list)));
}
}
Output:
{ "properties" : [ {
"property" : "email",
"value" : "abc@gmail.com"
}, {
"property" : "firstname",
"value" : "John"
} ] }
With a little effort you can re-factor the example to a custom serializer which can be plugged as documented here.