/
JsonUtils.java
121 lines (108 loc) · 4.99 KB
/
JsonUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.progressive.code.jdp;
import java.util.Optional;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
public class JsonUtils {
private static ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
/**
* Parses the given string and returns the corresponding {@link JsonNode} representation.
* @param jsonAsString the JSON data as String
* @return the corresponding {@link JsonNode}
* @throws JsonMappingException
* @throws JsonProcessingException
*/
public static JsonNode getJsonStringAsNode(String jsonAsString) throws JsonMappingException, JsonProcessingException {
return objectMapper.readTree(jsonAsString);
}
/**
* Looks up the field name in the given {@link JsonNode}. The method will return the first
* occurrence of the field name. Thus, most of the time it is better to
* use {@link #getNodeByPath(JsonNode, String)} when the entire path is known.
* @param jsonNode the {@link JsonNode} to search within
* @param fieldname the name of the field to search for
* @return an {@link Optional} of type {@link JsonNode}
*/
public static Optional<JsonNode> getNodeByName(JsonNode jsonNode, String fieldname) {
JsonNode node = jsonNode.findPath(fieldname);
if(node.isMissingNode()) {
return Optional.empty();
}
return Optional.of(node);
}
/**
* Looks up a {@link JsonNode} based on the given path. The path expression has to start with
* "/" and each sub-path ahs to be separated with "/" as well. Example: "/personalInfo/dateOfBirth".
* @param jsonNode the {@link JsonNode} to search within
* @param path the path expression, e.g. "/personalInfo/dateOfBirth"
* @return an {@link Optional} of type {@link JsonNode}
*/
public static Optional<JsonNode> getNodeByPath(JsonNode jsonNode, String path) {
JsonNode node = jsonNode.at(path);
if(node.isMissingNode()) {
return Optional.empty();
}
return Optional.of(node);
}
/**
* Looks up and returns the string value of the {@link JsonNode} specified by the path.
* @param jsonNode the root {@link JsonNode}
* @param path the path to the {@link JsonNode} to get the string value for
* @return an {@link Optional} of type {@link JsonNode}
*/
public static Optional<String> getValueAsString(JsonNode jsonNode, String path) {
Optional<JsonNode> textNode = getNodeByPath(jsonNode, path);
if(textNode.isPresent() && textNode.get().isTextual()) {
return Optional.of(textNode.get().asText());
}
return Optional.empty();
}
/**
* Creates or updates the string value of an element described by path.
* @param jsonNode the root {@link JsonNode}
* @param path the path to the {@link JsonNode} to set the string value for
* @param stringValue the value t oset
* @return true if the value could be set
*/
public static boolean setOrUpdateTextValue(JsonNode jsonNode, String path, String stringValue) {
// Extract parentPath and attribute name, given the path variable looks like
// /root/sub/sub/attributeName
int lastSeparator = path.lastIndexOf("/");
String attributeName = path.substring(lastSeparator+1);
JsonNode parentNode = getNodeByPath(jsonNode, path.substring(0, lastSeparator)).orElse(null);
// We have to ensure that the parent node exist and that the parent node is an object
if(parentNode == null || !parentNode.isObject()) {
return false;
}
// If the attribute already exists, we have to first remove it
if(parentNode.hasNonNull(attributeName)) {
((ObjectNode)parentNode).remove(attributeName);
}
// Add the attribute and it's value
((ObjectNode)parentNode).put(attributeName, stringValue);
return true;
}
/**
* Tries to locate an {@link ArrayNode} at the given path.
* @param jsonNode the root {@link JsonNode}
* @param path the path to the {@link ArrayNode}
* @return an {@link Optional} of type {@link ArrayNode}
*/
public static Optional<ArrayNode> getArrayNode(JsonNode jsonNode, String path) {
Optional<JsonNode> arrayNode = getNodeByPath(jsonNode, path);
if(!arrayNode.isPresent() || !arrayNode.get().isArray()) {
return Optional.empty();
}
return Optional.of((ArrayNode)arrayNode.get());
}
}