I'm developing a microservice (let's call it email microservice) which generates emails from HTML templates. Basically, the client sends a json with some data to the email microservice, and based on that data it has to generate an email (populate fields in html template with values coming in the json). The client is our other microservice, which prepares json and sends to the email microservice.
Json structure would be something like this:
{
"data":{
......
},
.......
}
"Data" is the dynamic object which can contain different things. So we can populate it with pairs key - value, for example, and then map to HashMap and then use this HashMap to populate our template, using some template engine (Velocity, thymeleaf or something else). Let's say we can prepare json like this:
{
"data":{
"userName":"Jack"
},
.......
}
And then use it in the template, something like this:
<b> Hello {{userName}}! </b>
This approach works fine, but I would like to simplify it, so we wouldn't need to prepare a proper json everytime (populate "data" field with key - value pairs), instead we would like just to put there some POJOs, without carrying which fields we need, and then use JsonPath in our templates to access required data. For example we create a json:
{
"data":{
"user": {
"firstName":"Jack",
..........
},
...........
},
.......
}
And in the template write something like that:
<b> Hello {{data.user.firstName}}! </b>
That would save us some time, cause we wouldn't need to cary about json structure.
Is there any template engine which can use a Json as input and access values by JsonPath? So I write something like this: data.user.firstName and the engine automatically finds value from the given json.
The problem was solved by using Velocity and JsonPath lib.
I've created a new tool for Velocity:
public class JsonPathTool {
private final String json;
public JsonPathTool(String json) {
this.json = json;
}
public Object valueAt(String jsonPath) {
jsonPath = "$." + jsonPath;
return JsonPath.read(this.json, jsonPath);
}
}
Then I put JsonPathTool in Velocity context:
VelocityContext ctx = new VelocityContext();
JsonPathTool jsonPathTool = new JsonPathTool(json);
ctx.put("data", jsonPathTool);
And in my templates I use following syntax:
"<b> Hello $data.valueAt(\"user.firstName\") </b>"
Related
I have a JSON which has an attribute with its List type. Can someone help me on how to read the value in Apache Velocity template? Following is an example of JSON. The challenge is to read the list of University from JSON and iterate through it.
{
"StudentName":"XYZ",
"List<Univesity>": [
{
"Name": "NYU",
"City": "NY",
"Country":"US",
} ]
}
The solution is dependent upon the JSON library you use, but for many of them, the following code should work:
#set( $universities = $document.get('List<University>') )
#foreach( $university in $universities )
... do something ...
#end
The main point to note here is that you can call any Java method on the object you get.
Also, if the security uberspector is not present, for debugging purposes you can display the Java class name of any object in the context, for instance: $document.class.name should display, in your case, something like com.fasterxml.jackson.databind.node.ObjectNode.
I am creating a JSON using the Jackson JsonGenerator approach and everything seems to work perfectly fine apart from a minor glitch. I would like to move the particular key present in the created JSON to the top of the JSON.
I am creating a key schema which appears at the bottom of the JSON. I would like to know if there is a way to move it to the top of the JSON after finished creating the JSON.
Following is the JSON that I am creating:
public class JacksonTest {
public static void main(String[] args) throws IOException {
StringWriter jsonObjectWriter = new StringWriter();
JsonGenerator jsonGenerator = new JsonFactory().createGenerator(jsonObjectWriter).useDefaultPrettyPrinter();
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("a", "Value-A");
jsonGenerator.writeStringField("c", "Value-C");
jsonGenerator.writeStringField("b", "Value-B");
jsonGenerator.writeStringField("schema", "2.0");
jsonGenerator.close();
jsonGenerator.flush();
System.out.println(jsonObjectWriter.toString());
}
}
Following is the output I am getting:
{
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B",
"schema" : "2.0"
}
I would like to convert the JSON something like this:
{
"schema" : "2.0",
"a" : "Value-A",
"c" : "Value-C",
"b" : "Value-B"
}
I would like to fetch the schema from my created JSON and add it to the top of the JSON.
Please Note:
I am aware the JSON order does not matter but I am doing this for better readability purposes. If there is a way then it would be really useful for the reader to understand the JSON better.
I am aware that I can create the schema at first in this code but this is just a sample application that I have provided for ease of understanding. In my real application, I have a Map that is populated dynamically throughout the execution and I am adding it at the end of the JSON creation. If I add at the first then I will miss out on a few of the values which are populated after creation so I am adding at the end but I want this to appear at the top of the JSON so trying to move to the top.
I want to know if there is a direct way to do it rather than looping over the JSON, as my created JSON in the real application can be pretty large.
I would really appreciate it if there was a way to do it or is there any workaround for this.
I am working with a some multi stage forms in my Scala Play application at the moment, the end result of this multi step form is to send a POST request to an end point with this JSON structure,
{{ "name":"Company Name", "contact": { "firstname":"Firstname1", "surname":"Surname1", "email":"firstname1.surname1#xyz.com", "textPhone":false, "phone":"12222222222222" }, "address": { "addressLine1":"Address Line 1", "town":"Town1", "county":"County", "postcode":"LS1 3DE" }
}
For each form submission I am doing the following,
request.session + ("organisation_name" -> formData.toString())
Is there away that I can have this JSON structure in a session and push the data to the correct attributes? Or is there a way that I can take the session data and manipulate it into JSON that follows the above format?
One way to add something to a session is like this:
request.session.copy(
data = request.session.data + ("organisation_name" -> formData.toString())
)
Another way to add to a session at the return point is like this:
Redirect(routes.......).addingToSession("organisation_name" -> formData.toString())
Have tried Storing your JSON object in request session.
Or u can try caching the JSON object with the Timestamp then read it from cache map so when u go back to the previous from u can Repopululate by getting its attributes.
I need to log message in json formate. Not like this
{
"level":"INFO",
"message": "log message"
}
I want to log json object which can be
{
"level":"INFO",
"json_att1":"value1",
"json_att2": "value2"
}
There is no message field in my wish. I just want to use the pseudo code
like this log.info(jsonObj)
The essential need is I want to add custom field in the json log
You can use link library.
Example:
String str = new JSONObject()
.put("level","debug")
.put("prop1", "val1").toString();
logger.debug(str);
I successfully followed the example Simple Spring code to parse JSON into a Java class structure using Jackson.
Now i am looking for a hint how to do the same for JSON data without key names, e.g.
{
"10869918": {
"BRANCH": "Dienstleistungen",
"SECTOR": "Diverse"
},
"12254991": {
"BRANCH": "Luft- und Raumfahrtindustrie",
"SECTOR": "Logistik"
},
"12302743": {
"BRANCH": "Touristik und Freizeit",
"SECTOR": "Medien/Freizeit"
}
}
I doubt this is possible with a POJO-JSON mapper. You could use libraries like json-simple to parse the JSON string into Java objects (which basically are maps and lists) and access values like "10869918" by reading the keys of those maps.