I'm trying to create POJOs for the following JSON structure. The Fields
node is easy enough to wire up, but I'm unsure how to use annotations to wire up the Description
node. If I had been defining the JSON structure for that node, I'd have create an JsonArray of JsonObjects, which would make the java class easy, but since I didn't, I need to figure out how to serialize the structure below:
{
"Fields": {
"Required": ["ftp.hostname"],
"Optional": ["ftp.rootDirectory"]
},
"Description": {
"ftp.hostname": {
"label": "SFTP Hostname",
"description": "SFTP server hostname or IP address"
},
"ftp.rootDirectory": {
"label": "Root Directory",
"description": "The root path on the Data Store accessible by this connector"
}
}
}
Note that the nodes in the Description
object have names that correlate to the values defined in the Fields
node, which means their node names can vary from payload to payload.
The class for the Fields
node:
public class FieldDetails {
public static final String REQUIRED = "Required";
public static final String OPTIONAL = "Optional";
@JsonProperty(value = REQUIRED, required = true)
private List<String> required;
@JsonProperty(value = OPTIONAL, required = true)
private List<String> optional;
}
And what I have so far for the entire object:
public class FieldDefinitions {
public static final String FIELDS = "Fields";
public static final String DESCRIPTION = "Description";
@JsonProperty(value = FIELDS, required = true)
private FieldDetails fields;
@JsonProperty(value = DESCRIPTION , required = true)
private ??? descriptions;
}
Generally, you can always map any JSON
object to Map<String, Object>
. If JSON
is complicated with many nested objects, Jackson
will automatically pick correct type: Map
for objects and List
for arrays.
You can also declare class like below for Description
properties.
class Description {
private String label;
private String description;
// getters, setters, toString
}
The whole Description
is a big JSON
which you can map to Map<String, Description>
. So, it could look like below:
class FieldDefinitions {
public static final String FIELDS = "Fields";
public static final String DESCRIPTION = "Description";
@JsonProperty(value = FIELDS, required = true)
private FieldDetails fields;
@JsonProperty(value = DESCRIPTION, required = true)
private Map<String, Description> descriptions;
// getters, setters, toString
}
Rest is the same. Example app:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.List;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File json = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
FieldDefinitions fields = mapper.readValue(json, FieldDefinitions.class);
System.out.println("Required");
fields.getFields().getRequired().forEach(r ->
System.out.println(r + " = " + fields.getDescriptions().get(r)));
System.out.println("Optional");
fields.getFields().getOptional().forEach(r ->
System.out.println(r + " = " + fields.getDescriptions().get(r)));
}
}
For given JSON
payload
prints:
Required
ftp.hostname = Description{label='SFTP Hostname', description='SFTP server hostname or IP address'}
Optional
ftp.rootDirectory = Description{label='Root Directory', description='The root path on the Data Store accessible by this connector'}