Toll Free:

1800 889 7020

Integrating AI with Spring Tutorial: Building Intelligent Applications with Spring AI

In the fast-paced world of technology, integrating artificial intelligence (AI) into applications has become essential for driving innovation and improving efficiency. The Spring AI Project is a powerful extension of the Spring framework, designed to make it easier to incorporate AI capabilities into Spring-based applications. Let us delve into understanding Spring AI and Spring AI Structured Outputs.

1. What is Spring AI?

The Spring AI Project extends the widely adopted Spring framework, providing a suite of tools and libraries that simplify the integration of AI functionalities into Spring applications. It bridges the gap between AI models and business applications, offering seamless integration, enhanced configurability, and strong support for various AI services and frameworks. Whether you’re working with machine learning models, natural language processing, or computer vision, Spring AI equips you with the components needed to effortlessly embed AI capabilities into your application. Spring AI offers three built-in classes—MapOutputConverter, ListOutputConverter, and BeanOutputConverter—that facilitate handling the most common response structures typically encountered in APIs. At a broad level, these converters serve two primary functions:

  • They guide the prompt to generate responses in a specified format (such as XML or JSON) and structure, ensuring consistent and precise output.
  • After receiving the response, they parse it into Java development services classes, including POJOs, Lists, or Maps, facilitating seamless integration with Java-based applications.

2. How to generate an OpenAI API key?

We’ll use an OpenAI model to generate a chat completion bot, so let’s first understand how to obtain an OpenAI key.

  • Create an Account or Sign In: Go to the OpenAI website and either sign up for a new account or log in to your existing one.
  • Access API Keys: After logging in, head to the API Keys section within your account dashboard.
  • Generate a New API Key: Select the option to create a new API key. Assign a name or description to the key for easy reference.
  • Generate and Save the Key: Click the Generate Key button. Make sure to copy the newly created API key and store it in a safe place, as you will need it to access OpenAI’s services.

3. Code example

3.1 Dependencies

Add the following dependencies to your pom.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springai-structuredoutput</name>
    <description>springai-structuredoutput</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>1.0.0-M2</spring-ai.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

3.2 Update the application properties

Add the following properties to the application.properties file. Remember to replace the OpenAI key.

# Application properties
spring.application.name=springai-structuredoutput
spring.main.banner-mode=off
server.port=9090

# OpenAI API key
spring.ai.openai.api-key=your-openai-api-key

3.3 Create a Model DTO

Create a Model DTO as it will be used for the BeanOutputConverter endpoint in the controller.

package com.demo.model;

public class Movie {

    private String category;
    private String book;
    private String year;
    private String review;
    private String author;
    private String summary;

    public Movie() {
    }

    public Movie(String category, String book, String year, String review, String author, String summary) {
        this.category = category;
        this.book = book;
        this.year = year;
        this.review = review;
        this.author = author;
        this.summary = summary;
    }

    // getter method
}

3.4 Creating the Controller

The ChatController class is a REST controller in a Spring Boot application, responsible for handling the HTTP requests related to Structured Ouput in Spring AI.

package com.demo.controller;

import com.demo.model.Movie;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.converter.ListOutputConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/chat")
public class ChatController {

    private final ChatClient client;

    @Autowired
    public ChatController(ChatClient.Builder builder) {
        this.client = builder.build();
    }

    /**
     * Handles GET requests to /chat/response.
     *
     * @param category the category of the movie
     * @param year     the year of the movie
     * @return a JSON string containing the movie details
     */
    // curl -X GET "http://localhost:9090/chat/response?category=action&year=2022"
    @GetMapping("/response")
    public String getResponse(@RequestParam String category, @RequestParam String year) {
        System.out.println("category: " + category);
        System.out.println("year: " + year);
        System.out.println("String response");
        return client.prompt()
                .user(user -> user.text("Please provide the movie detail for the given {category} and {year} in the JSON format.")
                        .param("category", category)
                        .param("year", year))
                .call()
                .content();

    }


    /**
     * Handles GET requests to /chat/beanResponse.
     *
     * @param category the category of the movie
     * @param year     the year of the movie
     * @return a Movie object containing the movie details
     */
    // curl -X GET "http://localhost:9090/chat/beanResponse?category=action&year=2022"
    @GetMapping("/beanResponse")
    public Movie getBeanResponse(@RequestParam String category, @RequestParam String year) {
        System.out.println("category: " + category);
        System.out.println("year: " + year);
        System.out.println("Bean response");
        return client.prompt()
                .user(user -> user.text("Please provide the movie detail for the given {category} and {year}.")
                        .param("category", category)
                        .param("year", year))
                .call()
                .entity(Movie.class);
    }

    /**
     * Handles GET requests to /chat/listResponse.
     *
     * @param category the category of the movie
     * @param year     the year of the movie
     * @return a list of strings containing the names of the best movies
     */
    // curl -X GET "http://localhost:9090/chat/listResponse?category=action&year=2022"
    @GetMapping("/listResponse")
    public List<String> getListResponse(@RequestParam String category, @RequestParam String year) {
        System.out.println("category: " + category);
        System.out.println("year: " + year);
        System.out.println("List response");
        return client.prompt()
                .user(user -> user.text("Please provide the names of 5 best movies for the given {category} and {year}.")
                        .param("category", category)
                        .param("year", year))
                .call()
                .entity(new ListOutputConverter(new DefaultConversionService()));
    }

    /**
     * Handles GET requests to /chat/mapResponse.
     *
     * @param category the category of the movie
     * @param year     the year of the movie
     * @return a map containing the movie details
     */
    // curl -X GET "http://localhost:9090/chat/mapResponse?category=action&year=2022"
    @GetMapping("/mapResponse")
    public Map<String, Object> getMapResponse(@RequestParam String category, @RequestParam String year) {
        System.out.println("category: " + category);
        System.out.println("year: " + year);
        System.out.println("Map response");
        return client.prompt()
                .user(u -> u.text("""
                                Please provide me best movie for the given {category} and the {year}.
                                Please do provide a summary of the movie as well, the information should be\s
                                limited and not much in depth. The response should be in the JSON format\s
                                containing this information:
                                category, movie, year, review, author, summary
                                Please remove ```json from the final output
                                """)
                        .param("category", category)
                        .param("year", year))
                .call()
                .entity(new ParameterizedTypeReference<>() {
                });
    }
}

3.5 Create the Main file

Create a Spring Boot application to initialize the application.

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringaiStructuredoutputApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringaiStructuredoutputApplication.class, args);
        System.out.println("Application started successfully.");
    }
}

3.6 Run the application and Demo

Now start the application and open the Postman tool to hit the api endpoint. Import the below curl GET requests in the Postman tool. You’re free to change the prompt with a valid instruction.

// Handles GET requests to /chat/response.
curl -X GET "http://localhost:9090/chat/response?category=action&year=2022"


// Handles GET requests to /chat/beanResponse.
http://localhost:9090/chat/beanResponse?category=action&year=2022


// Handles GET requests to /chat/listResponse.
http://localhost:9090/chat/listResponse?category=action&year=2022


// Handles GET requests to /chat/mapResponse.
http://localhost:9090/chat/mapResponse?category=action&year=2022

If everything goes well api responses in different formats will be returned and shown to the user.

4. Conclusion

In conclusion, as Generative AI Development Services continues to reshape the technological landscape, tools like Spring AI are essential for seamlessly integrating AI into applications. By leveraging Alternative to Spring boot AI, developers can easily add advanced AI capabilities to their Spring-based projects, enabling innovative solutions like generating images from user prompts, chat completion bots, etc.

5. Download the code

You can download the full code here: Download
 

Here is another Tutorial for Kafka migration to Spring Boot 3.X

Harsh Savani

Harsh Savani is an accomplished Business Analyst with a strong track record of bridging the gap between business needs and technical solutions. With 15+ of experience, Harsh excels in gathering and analyzing requirements, creating detailed documentation, and collaborating with cross-functional teams to deliver impactful projects. Skilled in data analysis, process optimization, and stakeholder management, Harsh is committed to driving operational efficiency and aligning business objectives with strategic solutions.

Scroll to Top