There is difference in between these 2 methods
- JsonNode.get() method returns null
- Use JsonNode.path(String).asText() which checks if node is present or not, if not then it returns empty string.
There is difference in between these 2 methods
- JsonNode.get() method returns null
- Use JsonNode.path(String).asText() which checks if node is present or not, if not then it returns empty string.
The convertValue function is used to convert one instance type into another instance type. It is a two step conversion process which is equivalent to first serializing given value into JSON, then binding JSON data into value of second given type.
In your example above, the first argument of convertValue is actually a JSON(represented in a string) and not an object, hence this does not work.
To make this work, you can use following methods :
Method 1 :
JsonNode node = jsonMapper.readTree(jsonRoot);
This will deserialize the json as a tree and returns the root of the tree which can be used for traversal now.
Method 2 :
JsonNode node = jsonMapper.readValue(jsonRoot, JsonNode.class);
This will deserialize the json to JsonNode object directly.
java - JsonNode.get("") returns null value. I want to take "name" and "forks" from json on code - Stack Overflow
Missing JsonNode field deserialized to null instead of NullNode
java - JsonNode.get().asText() returning null - Stack Overflow
java - Check if JSON node is null - Stack Overflow
To do a proper null check of a JsonNode field:
JsonNode jsonNode = response.get("item");
if(jsonNode == null || jsonNode.isNull()) { }
The item is either not present in response, or explicitly set to null .
OK, so if the node always exists, you can check for null using the .isNull() method.
Copyif (!response.isNull("item")) {
// do some things with the item node
} else {
// do something else
}
could you try this code?
JsonNode tree = mapper.readTree(file);
JsonNode solutionsArray = tree.get("solution");
if (solutionsArray != null && solutionsArray.isArray()) {
for (JsonNode node : solutionsArray) {
if (node.get("name") != null && node.get("name").asText().equalsIgnoreCase(name)) {
solution = mapper.treeToValue(node, solution.class);
System.out.println(solution.getName());
} else {
System.out.println("problem doesn't exist");
}
}
}
I think the issue is that you're trying to iterate over the root JsonNode, but your JSON structure wraps the actual array inside a solution field. Therefore, tree is not an array, and calling .get("name") on it will return null, causing the NullPointerException.
While the solution in the other answer works, I think you can make it easier and more natural for yourself by doing more modelling in Java, which will allow you to leave more of the parsing work to Jackson. In addition to your Solution class (which should be spelled with an uppercase letter as all Java class names) also write a little class to reflect your entire JSON. I recommend a record type:
record Problems (@JsonProperty("Solution") List<Solution> solution) {
public List<Solution> solutions() {
return Collections.unmodifiableList(solution);
}
}
Alternatively a classic class will work too:
public class Problems {
@JsonProperty("Solution")
private List<Solution> solution;
public List<Solution> getSolution() {
return Collections.unmodifiableList(solution);
}
}
I added the @JsonProperty annotation to inform Jackson that Solution is spelled with uppercase S in JSON even though the variable in Java must be spelled with a small s.
Now your method can be written like the following. I have inlined the JSON for a reproducible example.
public static Solution findSolution(String name){
String json = """
{
"Solution": [
{
"name":"twoSum",
"difficulty": "easy",
"status": "time exceeded",
"lastModified": "12-05-2025",
"testCase": false,
"source": "leetcode.com",
"language": "java"
},
{
"name": "Watermelon",
"difficulty": "easy",
"status": "working",
"lastModified": "05-02-2024",
"testCase": false,
"source": "codeforces.com",
"language": "C++"
}
]
}""";
ObjectMapper mapper = new ObjectMapper();
try {
Problems problems = mapper.readValue(json, Problems.class);
return problems.solution() // with the *class* Problems use .getSolution()
.stream()
.filter(sol -> sol.getName().equals(name))
.findAny()
.orElseThrow();
} catch (JsonProcessingException e){
e.printStackTrace();
}
System.out.println("problem doesnt exist");
return null;
}
In your code you can just use
Problems problems = mapper.readValue(file, Problems.class);
If you are not comfortable with the stream operation, you may also use a loop for finding the solution with the requested name.
Let’s try it out:
Solution sol = findSolution("Watermelon");
System.out.println(sol);
Output from the latter line is:
Solution{name='Watermelon', difficulty='easy', status='working', lastModified='05-02-2024', testCase='false', source='codeforces.com', language='C++'}
It looks like we have two different isEmpty( ) methods. I'm using Jackson for JsonNode:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.4</version></dependency>