Spring AI Day 4: Get LLMs to Return Java Objects Directly, No Manual Parsing
The article explains how Spring AI’s .entity() method lets developers obtain structured Java objects such as POJOs, lists, enums, and response entities directly from LLM outputs, eliminating the need for manual JSON parsing and handling generic‑type issues with ParameterizedTypeReference.
Problem: String‑to‑Object Gap
LLM calls return plain text, but business code often needs concrete POJOs like List<Movie> or a WeatherInfo object. The traditional approach requires prompting the model for JSON, using ObjectMapper to deserialize, and adding error‑handling for malformed JSON.
.entity(): Mapping Response to an Object
Spring AI encapsulates the whole workflow. Define a target record and replace .content() with .entity():
record ActorFilms(String actor, List<String> movies) {}
ActorFilms films = chatClient.prompt()
.user("Generate 5 movies starring Tom Hanks")
.call()
.entity(ActorFilms.class);
System.out.println(films.actor()); // Tom Hanks
System.out.println(films.movies()); // [Forrest Gump, Saving Private Ryan, ...]The BeanOutputConverter automatically appends a schema‑prompt ("return JSON matching this structure") and deserializes the model’s JSON into the specified type.
Returning Collections: ParameterizedTypeReference
To obtain a List<ActorFilms> you cannot use List.class because of type erasure. Instead, supply a ParameterizedTypeReference:
List<ActorFilms> list = chatClient.prompt()
.user("Generate 5 movies for Tom Hanks and Bill Murray")
.call()
.entity(new ParameterizedTypeReference<List<ActorFilms>>() {});Enums for Classification Tasks
Define an enum and let the model return one of its values, which is useful for sentiment analysis or intent classification:
enum Sentiment { POSITIVE, NEUTRAL, NEGATIVE }
Sentiment result = chatClient.prompt()
.user("Classify the sentiment of: 'The delivery was too slow, never buying again' ")
.call()
.entity(Sentiment.class); // NEGATIVEThe model is constrained to output only the defined enum constants, avoiding extraneous text.
Both Structured Object and Full ChatResponse: responseEntity()
If you need the deserialized object together with metadata such as token usage, use responseEntity():
ResponseEntity<ChatResponse, ActorFilms> re = chatClient.prompt()
.user("Generate 5 movies starring Tom Hanks")
.call()
.responseEntity(ActorFilms.class);
ActorFilms films = re.entity(); // the POJO
Usage usage = re.response().getMetadata().getUsage(); // token usageKey Takeaways
.entity(Class)– maps the LLM reply directly to a Java object. .entity(ParameterizedTypeReference) – handles generic collections. .entity(Enum.class) – enables classification tasks with enum constraints. responseEntity() – returns both the structured object and the full ChatResponse for metadata.
Underlying BeanOutputConverter generates the schema prompt and performs JSON deserialization automatically.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tech Ocean
Focused on AI programming, sharing ready-to-use development efficiency solutions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
