A safer, cleaner way to work with JSON-like structures.
Working with dynamic data in Java is like opening a mystery box. Sometimes everything’s where it should be. Other times? You’re five instanceof
checks deep and still getting NullPointerExceptions
.
If you’ve ever tried to pull data from a Map<String, Object>
that contains more maps inside, you’ve probably written something like this:
String username = (String) ((Map<String, Object>) payload.get("context")).get("username");
Looks innocent. Breaks easily.
Let’s fix that. We'll build a clean, safe, and reusable pattern to access nested data using Optional
and a couple of focused helper methods. You’ll write less boilerplate, and keep your business logic readable.
Let’s take a typical payload:
Map<String, Object> payload = new HashMap<>();
Map<String, Object> context = new HashMap<>();
context.put("username", "bruce.wayne");
payload.put("context", context);
You want the username
. The normal approach:
String username = (String) ((Map<String, Object>) payload.get("context")).get("username");
This line is a landmine as there can be multiple issues:
"context"
might not exist → NullPointerException
"context"
might not be a Map
→ ClassCastException
"username"
might be missing → NullPointerException
"username"
might not be a String
→ ClassCastException
This one line invites four possible runtime errors. You'll end up writing defensive code that buries the logic under a pile of instanceof
and != null
checks.
You can fix this in a number of steps:
public static Map<String, Object> get(Map<?, ?> map, String key) {
if (map == null) return new HashMap<>();
return Optional.ofNullable(key)
.map(map::get)
.filter(Map.class::isInstance)
.map(value -> {
@SuppressWarnings("unchecked")
Map<String, Object> nested = (Map<String, Object>) value;
return nested;
})
.orElse(new HashMap<>());
}
What this does:
Handles null
inputs
Ensures the value is actually a Map
Returns an empty map if things go wrong
Avoids exceptions and makes downstream code cleaner
public static <T> T get(Map<String, Object> map, String key, Class<T> clazz) {
if (map == null || key == null || clazz == null) return null;
Object value = map.get(key);
if (clazz.isInstance(value)) {
return clazz.cast(value);
}
return null;
}
What this does:
Fetches a value and casts it only if it's of the expected type
If it's not there, or not the right type, it returns null
Keeps things safe and type-checked without you doing the checks manually
Say you're always accessing the "Something"
map inside a payload. Here's a shortcut:
public static String getFromContext(Map<String, Object> payload, String key) {
Map<String, Object> context = get(payload, "Something");
return get(context, key, String.class);
}
Now this is all you write in your business logic:
String username = getFromContext(payload, "username");
That’s it. No fuss, no runtime chaos.
Map<String, Object> userDetails = new HashMap<>();
userDetails.put("username", "bruce.wayne");
userDetails.put("accessLevel", 2); // Integer, not String!
Map<String, Object> payload = new HashMap<>();
payload.put("Something", userDetails);
String username = getFromContext(payload,"username"); // bruce.wayne
String access = getFromContext(payload, "accessLevel"); // null
String email = getFromContext(payload, "email"); // null
The helpers return null
gracefully when something’s off and never crash your app.
Java’s generics don’t exist at runtime. That’s why we suppress the cast in get()
when converting to Map<String, Object>
.
@SuppressWarnings("unchecked")
Map<String, Object> nestedMap = (Map<String, Object>) value;
This works as long as the actual map has String keys and Object values. But if someone slips in a Map<Integer, String>
, you could get a ClassCastException
if you try to iterate using String keys.
For stricter safety, consider using libraries like Jackson to map JSON directly into typed classes.
If this article provided you with value, please consider buying me a coffee — only if you can afford it.
Join Vivek on Peerlist!
Join amazing folks like Vivek and thousands of other people in tech.
Create ProfileJoin with Vivek’s personal invite link.
0
11
0