Skip to content

Commit 5eea9d5

Browse files
committed
feat(util): add getJsonValue method for robust JSON parsing #11654
Introduced `getJsonValue` to parse serialized JSON strings into `JsonValue`, supporting `JsonObject`, `JsonArray`, and primitives. Includes comprehensive unit tests for valid and invalid JSON scenarios. Note: a primitive (number, string, ...) is not a valid JSON document on its own. The exception thrown is intended to be used to handle this situation. As this is related to the Settings Service, this may be used to return the raw value instead of some JSON object/array.
1 parent 3ce5875 commit 5eea9d5

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

src/main/java/edu/harvard/iq/dataverse/util/json/JsonUtil.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
import java.io.StringWriter;
99
import java.util.HashMap;
1010
import java.util.Map;
11+
import java.util.Objects;
1112
import java.util.logging.Logger;
1213
import jakarta.json.Json;
1314
import jakarta.json.JsonArray;
1415
import jakarta.json.JsonException;
1516
import jakarta.json.JsonObject;
1617
import jakarta.json.JsonReader;
18+
import jakarta.json.JsonValue;
1719
import jakarta.json.JsonWriter;
1820
import jakarta.json.JsonWriterFactory;
1921
import jakarta.json.stream.JsonGenerator;
@@ -131,4 +133,34 @@ public static JsonArray getJsonArray(String serializedJson) {
131133
}
132134
}
133135
}
136+
137+
138+
/**
139+
* Parses a serialized JSON string and returns it as a JsonValue.
140+
* The returned JsonValue can be a JsonObject, JsonArray, or another type
141+
* based on the structure of the provided serialized JSON string.
142+
* This method closes its resources but does not catch any exceptions.
143+
*
144+
* @param serializedJson The JSON content serialized as a String
145+
* @return The parsed content as a JsonValue which could be a JsonObject, JsonArray, or another JsonValue type
146+
* @throws JsonException If an error occurs during parsing (null, invalid JSON, not trimmed, etc.)
147+
*/
148+
public static JsonValue getJsonValue(String serializedJson) {
149+
if (serializedJson == null) {
150+
throw new JsonException("The serialized JSON string cannot be null.");
151+
}
152+
153+
try (StringReader rdr = new StringReader(serializedJson)) {
154+
try (JsonReader jsonReader = Json.createReader(rdr)) {
155+
JsonValue jsonValue = jsonReader.read();
156+
if (jsonValue.getValueType() == JsonValue.ValueType.OBJECT) {
157+
return jsonValue.asJsonObject();
158+
} else if (jsonValue.getValueType() == JsonValue.ValueType.ARRAY) {
159+
return jsonValue.asJsonArray();
160+
} else {
161+
return jsonValue;
162+
}
163+
}
164+
}
165+
}
134166
}

src/test/java/edu/harvard/iq/dataverse/util/json/JsonUtilTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
package edu.harvard.iq.dataverse.util.json;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import jakarta.json.JsonException;
7+
import jakarta.json.JsonValue;
8+
import org.junit.jupiter.api.Nested;
49
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.NullAndEmptySource;
12+
import org.junit.jupiter.params.provider.ValueSource;
513

614
class JsonUtilTest {
715

@@ -15,5 +23,32 @@ void testPrettyPrint() {
1523
assertEquals("[\n \"junk\"\n]", JsonUtil.prettyPrint("[\"junk\"]"));
1624
assertEquals("{\n" + " \"foo\": \"bar\"\n" + "}", JsonUtil.prettyPrint("{\"foo\": \"bar\"}"));
1725
}
18-
26+
27+
@Nested
28+
class JsonValues {
29+
@Test
30+
void testGetJsonValueWithJsonObject() {
31+
String jsonObject = "{\"key\": \"value\"}";
32+
JsonValue result = JsonUtil.getJsonValue(jsonObject);
33+
assertEquals(JsonValue.ValueType.OBJECT, result.getValueType());
34+
assertEquals("value", result.asJsonObject().getString("key"));
35+
}
36+
37+
@Test
38+
void testGetJsonValueWithJsonArray() {
39+
String jsonArray = "[\"element1\", \"element2\"]";
40+
JsonValue result = JsonUtil.getJsonValue(jsonArray);
41+
assertEquals(JsonValue.ValueType.ARRAY, result.getValueType());
42+
assertEquals("element1", result.asJsonArray().getString(0));
43+
assertEquals("element2", result.asJsonArray().getString(1));
44+
}
45+
46+
@ParameterizedTest
47+
@NullAndEmptySource
48+
@ValueSource(strings = {" ", " \"\"", "\"primitive\"", "{invalid}", "[invalid]", "[1234, invalid]"})
49+
void testGetJsonValueWithInvalidJson(String sut) {
50+
assertThrows(JsonException.class, () -> JsonUtil.getJsonValue(sut));
51+
}
52+
}
53+
1954
}

0 commit comments

Comments
 (0)