Skip to content

Commit 18ae16e

Browse files
ohMarufilayaperumalg
authored andcommitted
fix(json): prevent double-serialization of already valid JSON strings in JsonParser.toJson
If the input to JsonParser.toJson is a String that is already a valid JSON (e.g. a JSON array or object), the method now returns the string as-is, instead of re-serializing it into a quoted string. This avoids issues with deserialization errors, especially when tools expect structured types like List<T>. test(json): add unit test to ensure toJson skips serialization of valid JSON strings Signed-off-by: Ahmed Maruf <[email protected]>
1 parent 8283404 commit 18ae16e

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

spring-ai-model/src/main/java/org/springframework/ai/util/json/JsonParser.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,25 @@ public static <T> T fromJson(String json, TypeReference<T> type) {
100100
}
101101

102102
/**
103-
* Converts a Java object to a JSON string.
103+
* Checks if a string is a valid JSON string.
104+
*/
105+
private static boolean isValidJson(String input) {
106+
try {
107+
OBJECT_MAPPER.readTree(input);
108+
return true;
109+
}
110+
catch (JsonProcessingException e) {
111+
return false;
112+
}
113+
}
114+
115+
/**
116+
* Converts a Java object to a JSON string if it's not already a valid JSON string.
104117
*/
105118
public static String toJson(@Nullable Object object) {
119+
if (object instanceof String && isValidJson((String) object)) {
120+
return (String) object;
121+
}
106122
try {
107123
return OBJECT_MAPPER.writeValueAsString(object);
108124
}

spring-ai-model/src/test/java/org/springframework/ai/tool/method/MethodToolCallbackGenericTypesTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void testGenericListType() throws Exception {
6363
String result = callback.call(toolInput);
6464

6565
// Verify the result
66-
assertThat(result).isEqualTo("\"3 strings processed: [one, two, three]\"");
66+
assertThat(result).isEqualTo("3 strings processed: [one, two, three]");
6767
}
6868

6969
@Test
@@ -97,7 +97,7 @@ void testGenericMapType() throws Exception {
9797
String result = callback.call(toolInput);
9898

9999
// Verify the result
100-
assertThat(result).isEqualTo("\"3 entries processed: {one=1, two=2, three=3}\"");
100+
assertThat(result).isEqualTo("3 entries processed: {one=1, two=2, three=3}");
101101
}
102102

103103
@Test
@@ -134,7 +134,7 @@ void testNestedGenericType() throws Exception {
134134
String result = callback.call(toolInput);
135135

136136
// Verify the result
137-
assertThat(result).isEqualTo("\"2 maps processed: [{a=1, b=2}, {c=3, d=4}]\"");
137+
assertThat(result).isEqualTo("2 maps processed: [{a=1, b=2}, {c=3, d=4}]");
138138
}
139139

140140
/**

spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,13 @@ void fromScientificNotationToLong() {
255255
assertThat(value).isEqualTo(1_500_000_000_000L);
256256
}
257257

258+
@Test
259+
void doesNotDoubleSerializeValidJsonString() {
260+
String input = "[1,2,3]";
261+
String result = JsonParser.toJson(input);
262+
assertThat(input).isEqualTo(result);
263+
}
264+
258265
record TestRecord(String name, Integer age) {
259266
}
260267

0 commit comments

Comments
 (0)