From ce9f2fd1c8f0317dd3959a098f053ab86ce48e80 Mon Sep 17 00:00:00 2001 From: bourne7 Date: Wed, 6 Aug 2025 22:30:10 +0800 Subject: [PATCH] feat: Eliminate one deserialization step in the majority of scenarios when parsing Model response Signed-off-by: bourne7 --- .../ai/util/json/JsonParser.java | 18 ++++++++++-- .../ai/util/json/JsonParserTests.java | 28 +++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/spring-ai-model/src/main/java/org/springframework/ai/util/json/JsonParser.java b/spring-ai-model/src/main/java/org/springframework/ai/util/json/JsonParser.java index 7c22b6ed2cb..7b155e58c3c 100644 --- a/spring-ai-model/src/main/java/org/springframework/ai/util/json/JsonParser.java +++ b/spring-ai-model/src/main/java/org/springframework/ai/util/json/JsonParser.java @@ -168,8 +168,22 @@ else if (javaType.isEnum()) { return Enum.valueOf((Class) javaType, value.toString()); } - String json = JsonParser.toJson(value); - return JsonParser.fromJson(json, javaType); + Object result = null; + if (value instanceof String jsonString) { + try { + result = JsonParser.fromJson(jsonString, javaType); + } + catch (Exception e) { + // ignore + } + } + + if (result == null) { + String json = JsonParser.toJson(value); + result = JsonParser.fromJson(json, javaType); + } + + return result; } } diff --git a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java index 61e073b701b..924d94a422f 100644 --- a/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java +++ b/spring-ai-model/src/test/java/org/springframework/ai/util/json/JsonParserTests.java @@ -16,11 +16,11 @@ package org.springframework.ai.util.json; -import java.lang.reflect.Type; - import com.fasterxml.jackson.core.type.TypeReference; import org.junit.jupiter.api.Test; +import java.lang.reflect.Type; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -241,6 +241,22 @@ var record = new TestRecord("John", 30); assertThat(value).isEqualTo(new TestRecord("John", 30)); } + @Test + void fromStringToObject() { + String jsonString = """ + { + "name": "foo", + "age": 7 + } + """; + var value = JsonParser.toTypedObject(jsonString, TestSimpleObject.class); + assertThat(value).isOfAnyClassIn(TestSimpleObject.class); + + TestSimpleObject testSimpleObject = (TestSimpleObject) value; + assertThat(testSimpleObject.name).isEqualTo("foo"); + assertThat(testSimpleObject.age).isEqualTo(7); + } + @Test void fromScientificNotationToInteger() { var value = JsonParser.toTypedObject("1.5E7", Integer.class); @@ -265,6 +281,14 @@ void doesNotDoubleSerializeValidJsonString() { record TestRecord(String name, Integer age) { } + static class TestSimpleObject { + + public String name; + + public int age; + + } + enum TestEnum { VALUE