JSON Structural Transformation: Key and Value Swapping Between Objects
A common requirement when integrating systems is to reshape JSON payloads—renaming keys, copying values, or populating fields with dynamic data such as timestamps. A mapping‑based approach can handle these transformations declaratively. This article demonstrates how to swap keys and values between two JSON object structures using a Java utility.
Transformation Mapping Configuration
The core of the transformation is a list of mapping rules. Each rule specifies:
- target path – the location in the destination JSON wheree the result will be placed.
- source path – the location in the source JSON from which data is retrieved.
- transform type – the operation to perform:
1: copy source key → target key2: copy source key → target value3: copy source value → target key4: copy source value → target value
- options – additional flags to array handling, key generation, and mapping strategy.
A mapping rule is represented as a simple object:
{
"targetPath": "root.dev_aim",
"sourcePath": "root.dev_org",
"type": 1
}
Example: Swapping Keys and Values
Given the following source and a target template:
Source JSON:
{
"dev_org": {
"642fccd1_org": {
"1_org": "111_org",
"2_org": "222_org"
}
},
"time_org": 1682471111
}
Target Template (provides the desired key structure):
{
"dev_aim": {
"642fccd1_aim": {
"1_aim": "111_aim",
"2_aim": "222_aim"
}
},
"time_aim": 1682472222
}
The goal is to transform the source so that:
- keys
dev_org,642fccd1_org,1_org,2_org, andtime_orgare renamed to their_aimcounterparts. - values under
1_org,2_orgare preserved. - the
time_aimfield is filled with the current UTC timestamp instead of the original number.
Java Implementation
The transformation engine accepts a source string, a target template, and a list of rules. The following code sets up the required mappings and executes the conversion:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;
public class JsonKeyValueSwap {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
String sourceJson = "{\"dev_org\":{\"642fccd1_org\":{\"1_org\":\"111_org\",\"2_org\":\"222_org\"}},\"time_org\":1682471111}";
String targetTemplate = "{\"dev_aim\":{\"642fccd1_aim\":{\"1_aim\":\"111_aim\",\"2_aim\":\"222_aim\"}},\"time_aim\":1682472222}";
List<TransformationRule> rules = new ArrayList<>();
// Rename top-level key
rules.add(new TransformationRule("root.dev_aim", "root.dev_org", 1));
// Rename nested object key
rules.add(new TransformationRule("root.dev_aim.642fccd1_aim", "root.dev_org.642fccd1_org", 1));
// First inner key and value
rules.add(new TransformationRule("root.dev_aim.642fccd1_aim.1_aim", "root.dev_org.642fccd1_org.1_org", 1));
rules.add(new TransformationRule("root.dev_aim.642fccd1_aim.1_aim", "root.dev_org.642fccd1_org.1_org", 4));
// Second inner key (treat source value as target key)
rules.add(new TransformationRule("root.dev_aim.642fccd1_aim.2_aim", "root.dev_org.642fccd1_org.2_org", 3));
rules.add(new TransformationRule("root.dev_aim.642fccd1_aim.2_aim", "root.dev_org.642fccd1_org.2_org", 4));
// Time key
rules.add(new TransformationRule("root.time_aim", "root.time_org", 1));
// Replace value with current time (using a built‑in placeholder)
rules.add(new TransformationRule("root.time_aim", "#Time#", 4));
JsonTransformer transformer = new JsonTransformer(sourceJson, targetTemplate, rules);
String result = transformer.transform();
System.out.println("Transformed JSON:\n" + result);
}
}
The TransformationRule class encapsulates target path, source path, and type, while JsonTransformer processes the rules. The special placeholder #Time# injects the current UTC timestamp when used as a source value with type 4.
Expected output (keys match the target template, values come from the source, and time is replaced by a current ISO‑8601 string):
{
"dev_aim": {
"642fccd1_aim": {
"1_aim": "111_org",
"2_aim": "222_org"
}
},
"time_aim": "2024-03-21T07:28:54.893Z"
}
By composing rules of different types, you can remodel almost any JSON structure without writing custom procedural code.