eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – All Access – NPI EA (cat= Spring)
announcement - icon

All Access is finally out, with all of my Spring courses. Learn JUnit is out as well, and Learn Maven is coming fast. And, of course, quite a bit more affordable. Finally.

>> GET THE COURSE
Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Overview

Spring AI 2.0 brings the official OpenAI Java SDK into its standard OpenAI integration. We can use it through Spring’s abstractions while letting Spring Boot configure the underlying client.

In this tutorial, we’ll summarize a support request with ChatClient, configure Gemini as an optional provider, and migrate from the former separate SDK module.

2. How Spring AI Uses the OpenAI Java SDK

Spring AI provides a common API for working with language models. For this integration, ChatClient delegates to OpenAiChatModel, which translates Spring messages and options into requests handled by the official SDK.

Our application depends on Spring AI’s abstractions. The SDK handles the underlying API calls.

Spring Boot auto-configuration supplies the model and a ChatClient.Builder. This differs from using the OpenAI Java client directly, where we construct SDK requests ourselves.

Spring AI 2.0 removes the separate spring-ai-openai-sdk module. The standard OpenAI integration now uses the official SDK internally. In Spring AI 2.0.2, this integration uses the Chat Completions API and doesn’t support OpenAI’s Responses API.

3. Setting Up the Integration

Our example uses Java 21, Spring Boot 4.1.2, and Spring AI 2.0.2.

3.1. Maven Dependencies

In our Spring Boot project, let’s add the OpenAI starter:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
    <version>2.0.2</version>
</dependency>

The latest spring-ai-starter-model-openai version is available in the Maven Repository. Version 2.0.2 brings in openai-java-core 4.80.0 transitively, so we don’t need a separate SDK dependency.

3.2. Credentials and Model Configuration

We need an OpenAI API key and available API credits. Let’s supply the key through the OPENAI_API_KEY environment variable.

In application.yml, let’s configure the endpoint and limit the example’s response size:

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      base-url: https://api.openai.com/v1
      timeout: 30s
      max-retries: 0
      chat:
        model: ${OPENAI_MODEL:gpt-6-luna}
        reasoning-effort: none
        max-completion-tokens: 256

The full base URL includes /v1. The SDK appends /chat/completions when making our request.

For GPT-6 Luna, reasoning-effort: none disables reasoning, while max-completion-tokens caps generated tokens. We also set a request timeout and disable automatic retries to keep this small example’s API calls predictable.

4. Calling OpenAI-Compatible Models Through ChatClient

We want to send a synthetic support request and ask for a one-sentence summary containing the problem and requested action.

4.1. Creating the Summary Service

Let’s inject the auto-configured builder into our service:

@Service
public class SupportSummaryService {
    private final ChatClient chatClient;

    public SupportSummaryService(ChatClient.Builder builder) {
        this.chatClient = builder.defaultSystem(
          "Summarize the support request in one sentence. "
            + "Include the problem and the requested action. "
            + "Do not invent details.")
          .build();
    }

    public String summarize(String request) {
        return chatClient.prompt()
          .user(request)
          .call()
          .content();
    }
}

defaultSystem() establishes the summarization instruction. Each summarize() call adds the request as a user message, invokes the model synchronously, and returns its text.

The broader ChatClient fluent API also supports features such as streaming and structured output. Here, a plain string lets us focus on the SDK integration.

4.2. Verifying the OpenAI Call

Our Spring Boot test injects SupportSummaryService and exercises it with a duplicate-charge request:

String summary = summaryService.summarize(
  "I was charged twice for my subscription. Please refund the duplicate charge.");

assertThat(summary).isNotBlank();
logger.info("OpenAI support summary: {}", summary);

After setting our API key, let’s run the repository’s live test from the spring-ai-modules/spring-ai-openai directory:

$ export OPENAI_API_KEY='our-openai-api-key'
mvn test -Dtest=OpenAiSupportSummaryLiveTest

Both live tests use @EnabledIfEnvironmentVariable, so Maven reports a skipped test if the corresponding API key environment variable is missing or empty.

In our live run, OpenAI returned:

I was charged twice for my subscription and request a refund for the duplicate charge.

The generated wording can vary, so we should check for nonblank output rather than an exact sentence.

4.3. Using Gemini as an Alternative

For an alternative without paid OpenAI access, we can use Gemini’s OpenAI-compatible endpoint. Gemini 3.5 Flash-Lite offers a free tier, subject to quotas and availability.

In application-gemini.yml, a separate Spring profile overrides the provider settings:

spring:
  ai:
    openai:
      api-key: ${GEMINI_API_KEY}
      base-url: https://generativelanguage.googleapis.com/v1beta/openai/
      timeout: 120s
      chat:
        model: ${GEMINI_MODEL:gemini-3.5-flash-lite}
        reasoning-effort: low
        max-completion-tokens: 1024

The service and SDK stay the same, but model-specific options still matter. Gemini 3 models can’t disable thinking, so we should replace none with low and allow more tokens.

We allow up to 120 seconds per request. The live test’s 180-second limit prevents JUnit from interrupting the request first.

The Gemini live test activates this profile itself, so we only need its key and test name:

$ export GEMINI_API_KEY='our-gemini-api-key'
mvn test -Dtest=GeminiSupportSummaryLiveTest

Our Gemini 3.5 Flash-Lite run returned:

The user was charged twice for their subscription and is requesting a refund for the duplicate charge.

5. Migrating From the Separate SDK Module

This migration applies to the former spring-ai-openai-sdk integration. The upgrade notes describe its removal in Spring AI 2.0.

Applications already using the standard OpenAI module can keep their existing configuration properties, with chat.options.* retained as deprecated aliases. However, code that builds OpenAiChatModel manually needs updating.

In 2.0.2, OpenAiApi is gone. The model builder no longer provides openAiApi(), defaultOptions(), or retryTemplate(). It accepts the SDK’s OpenAIClient through openAiClient() and model settings through options().

5.1. Updating the Starter and Properties

When moving from Spring AI 1.1.x to 2.0.2, we also need a compatible Spring Boot 4 application. We should replace spring-ai-starter-model-openai-sdk with the starter shown in Section 3.1.

A configuration for the old SDK starter could contain:

spring.ai.openai-sdk.api-key=${OPENAI_API_KEY}
spring.ai.openai-sdk.base-url=https://api.openai.com/v1
spring.ai.openai-sdk.chat.options.model=gpt-6-luna

For Spring AI 2.0.2, the equivalent properties are:

spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.base-url=https://api.openai.com/v1
spring.ai.openai.chat.model=gpt-6-luna

The prefix changes from spring.ai.openai-sdk to spring.ai.openai. Let’s use the flat chat.model property. The older chat.options.model spelling still works in 2.0.2, but it’s deprecated.

5.2. Updating Model Classes and Options

Code that referenced the separate module’s types needs these replacements:

  • OpenAiSdkChatModel becomes OpenAiChatModel
  • OpenAiSdkChatOptions becomes OpenAiChatOptions

The package changes from org.springframework.ai.openaisdk to org.springframework.ai.openai. This affects explicit model construction and programmatic options, even when the application’s prompt stays the same.

The former OpenAiSdkChatModel builder already used openAiClient() and options(), so these method names carry over when we rename the class.

Our service only uses ChatClient.Builder and ChatClient, so it doesn’t reference either SDK-specific class. The starter and configuration change while its summarization code remains unchanged.

6. Conclusion

In this article, we used Spring AI’s standard OpenAI starter to summarize a support request through the official Java SDK. The same service worked with Gemini after changing the endpoint, credentials, and model options.

For applications using the removed SDK module, migration involves the starter, property prefix, and SDK-suffixed classes. Keeping application code centered on ChatClient limits the changes needed in the service layer.

The complete example is available over on GitHub.

Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)
guest
0 Comments
Oldest
Newest