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.

Tech Ocean
Tech Ocean
Tech Ocean
Spring AI Day 4: Get LLMs to Return Java Objects Directly, No Manual Parsing

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); // NEGATIVE

The 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 usage

Key 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaLLMSpring AIentity()structured outputParameterizedTypeReference
Tech Ocean
Written by

Tech Ocean

Focused on AI programming, sharing ready-to-use development efficiency solutions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.