I want to generate valid JSON with the help of a template engine. In particular, I want the engine to replace the placeholders in the template with the properties of a model class.
The engine should allow the use converters for complex classes like java.util.Date
.
Additionally, I do not want to explicitly handle lists in the template itself, instead I want any collection-like type to produce valid JSON arrays.
This could be an example of a template:
{
"uber" :
{
"version" : "1.0",
"data" :
[
{
"rel" : $relations,
"data" :
[
{"name" : "firstname", "value" : $firstname},
{"name" : "lastname", "value" : $lastname}
]
}
]
}
}
I want to replace the variables ($relations
, $firstname
, $lastname
) in this template from a model that has a relations, a firstname and a lastname property. This should also work for nested properties. (for example: $address.street
)
After binding the model, the JSON could look like this:
{
"uber" :
{
"version" : "1.0",
"data" :
[
{
"rel" : ["person"],
"data" :
[
{"name" : "firstname", "label" : "Firstname", "value" : "Max"},
{"name" : "lastname", "label" : "Lastname", "value" : "Mustermann"}
]
}
]
}
}
Please note, that the engine needs to take care of using quotation marks when necessary.
Is there any template library that is capable of doing this or do I need to roll my own library?
I have already looked into the following libraries:
And I also read several threads:
However, I did not find a satisfying solution up to now.
Background information:
Uber is domain-agnostic hypermedia format that nests data
elements in order to encode the data.
This format is very cumbersome to produce if you want to serialize it with a library like Jackson because you have to create a lot of objects and nested them via setters which results in a lot of code and is also very error-prone.
That is why I thought of using templates to generate the output and let the user write a template and later bind a model to this template to generate the output.
I found an answer to my question:
I am using the following notation for variables in my template: $(json.path.to.value)
.
I have implemented a custom Predicate
from the JsonPath library by JayWay that looks for values in the JSON which conform to the variable definition.
The predicate also takes a DocumentContext
which represents the model object, from which the values for the variables should be taken. This document context is created by serializing the model object with Jackson and re-reading it with the JsonPath library. This way, it is ensured that all tokens that are inserted in the template are valid JSON tokens.
If the predicate finds a variable, it extracts the containted JsonPath expression, looks for a new value in the provided DocumentContext
and overrides the value in the original JSON.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With