JsonUtil Tutorial
JsonUtil is a static facade for JSON serialization, parsing, and object conversion. It delegates work to a
JsonEngine, so callers do not need to expose implementation-specific types such as Jackson ObjectMapper or
JsonNode.
Introduction
JsonUtil provides common JSON operations between JSON strings, Java objects, Maps, and Lists through the configured
JSON engine.
Main Features
- Convert Java objects to JSON strings (pretty or compact)
- Parse JSON strings into Java objects
- Convert between JSON and Maps/Lists
- Type-safe JSON processing
- A lazily initialized, safely published shared
JsonEngine - An implementation-independent JSON tree returned as
Object
Methods
1. Serialization (to JSON)
toJson(Object obj)- Convert object to JSON stringtoJsonPretty(Object obj)- Convert object to pretty-printed JSON
2. Deserialization (from JSON)
fromJson(String jsonStr, Class<T> valueType)- Parse JSON to specified type
3. JSON ↔ Map Conversion
json2map(String jsonStr)- JSON to Map<String, Object>json2map(String jsonStr, Class<T> clazz)- JSON to Map with typed valuesjson2sortMap(String jsonStr, Class<T> clazz)- JSON to LinkedHashMap preserving orderjson2StrMap(String jsonStr)- JSON to Map<String, String>
4. JSON ↔ List Conversion
json2list(String jsonArrayStr, Class<T> clazz)- JSON array to Listjson2mapList(String jsonArrayStr)- JSON array to List
5. Object Conversion
convertValue(Object obj, Class<T> clazz)- Convert object typespojo2map(Object obj)- Convert POJO to Mappojo2map(Object obj, Class<T> clazz)- Convert POJO to typed Mapmap2pojo(Map<String, Object> map, Class<T> clazz)- Convert Map to POJO
6. JSON Tree Model
json2Node(String jsonStr)- Parse JSON to an engine-specific tree object
Usage Examples
Basic Serialization
User user = new User("John", 30);
String json = JsonUtil.toJson(user);
// {"name":"John","age":30}
String prettyJson = JsonUtil.toJsonPretty(user);
/*
{
"name" : "John",
"age" : 30
}
*/
Basic Deserialization
String json = "{\"name\":\"John\",\"age\":30}";
User user = JsonUtil.fromJson(json, User.class);
Map Conversion
Map<String, Object> map = new HashMap<>();
map.put("name", "John");
map.put("age", 30);
String json = JsonUtil.toJson(map);
Map<String, Object> map2 = JsonUtil.json2map(json);
List Conversion
String jsonArray = "[{\"name\":\"John\"}, {\"name\":\"Alice\"}]";
List<User> users = JsonUtil.json2list(jsonArray, User.class);
Engine configuration
On first use, JsonUtil.getEngine() loads JsonEngineProvider implementations through Java ServiceLoader and
selects the provider with the highest priority. The project provides a Jackson 2 engine when its optional Jackson
dependencies are present, but the facade itself is not tied to Jackson.
An application may set an engine explicitly before its first conversion:
JsonUtil.setEngine(myJsonEngine);
setEngine(null) is rejected. Replacing the engine changes subsequent calls globally, so configure it during
application startup rather than concurrently with ordinary JSON work. Date support, duplicate-key handling, time zone
behavior, and the concrete tree-model type are engine-specific rather than guarantees of JsonUtil.
Map, bean, and tree examples
Map<String, Object> source = new LinkedHashMap<>();
source.put("name", "Ada");
source.put("age", 36);
String json = JsonUtil.toJson(source);
Map<String, String> strings = JsonUtil.json2StrMap(json);
Map<String, Object> values = JsonUtil.json2map(json);
User user = JsonUtil.map2pojo(values, User.class);
Map<String, Object> userValues = JsonUtil.pojo2map(user);
json2sortMap requests a LinkedHashMap so parsed key order is retained. convertValue delegates to the selected
engine's object-conversion facility and is useful when the desired target type is known at runtime. json2Node is for
engine-specific tree traversal; cast its result only when the chosen engine is known.
Lifecycle and failures
The first engine is cached in a volatile field after lazy creation. If no JsonEngineProvider is visible to the
runtime class loader, getEngine() throws IllegalStateException. fromJson wraps parser/mapper failures in a
RuntimeException with the original cause. Other methods delegate directly and may expose provider-specific
exceptions. Do not log untrusted raw JSON merely because a conversion failed.
Implementation notes
JsonUtil keeps the selected engine in a volatile field and uses synchronized double-checked initialization. This
means normal calls avoid locking after startup while still publishing a fully created engine safely. Providers are
discovered through Java's standard ServiceLoader, then compared by their declared priority; this lets applications
replace the JSON backend without changing JsonUtil callers.
The facade deliberately exposes Object for json2Node: returning a library-specific tree type here would make the
common module permanently depend on that library. The trade-off is that tree processing code must know which provider
is active.
Conclusion
The JsonUtil class provides comprehensive utility methods for working with JSON data, making it easier to serialize,
deserialize, and convert between JSON and Java objects.