Blog

Simplifying Java AI development with Vaadin and Spring AI

By  
Sami Ekblad
Sami Ekblad
·
On May 17, 2024 11:32:42 AM
·

“Fight for Simplicity” has always been our motto. Personally, that has meant I want to keep simplifying my code. This post is an example of that effort, showcasing how Vaadin and Spring AI simplify the integration of AI into Java applications.

Revisiting AI integration in Vaadin applications

A year ago, you could read about Harnessing Generative AI for Business Applications. This insightful post explored the potential of integrating AI into Vaadin applications, highlighting practical tips and examples. Then, Marcus wrote a series building a chatbot for documentationSince then, AI technology has evolved rapidly, simplifying development. It’s time to revisit this topic with a fresh approach for Java AI applications.

Why Java AI with Vaadin and Spring AI?

Since Vaadin Flow is a Java framework for building modern web applications, its ease of use and strong integration capabilities make it an excellent choice for developers looking to add sophisticated features to their apps. Spring AI, on the other hand, provides a straightforward way to incorporate AI functionalities. By merging these two technologies, you can create dynamic, responsive Java AI applications with minimal effort.

What you'll need:

  • Vaadin Flow: For building the UI and layout. Vaadin handles the WebSocket-based communication. 
  • Vaadin Add-ons: We'll use MarkdownMessage from the Viritin add-on to show nicely formatted output.
  • Spring AI: For integrating AI capabilities.

Spring AI simplifies the integration of AI models into your Spring applications. It provides a set of APIs to interact with various AI services, making it easier to incorporate features like natural language processing and computer vision:

  • Model management: Easily manage and deploy different AI models.
  • Inference APIs: Perform real-time predictions and analysis using pre-trained models.
  • Streaming support: Stream data to and from AI services for dynamic and interactive applications.

These capabilities enable developers to build sophisticated AI-driven features without delving into the complexities of AI model training and deployment.

Setting up a Java AI project with Vaadin and Spring AI

1. Project setup

Start by creating a new Spring Boot project with Vaadin and Spring AI dependencies. You can use Spring Initializr to bootstrap your project quickly. It will add the necessary dependencies to your pom.xml, but nothing else. Simple, and you can continue with writing the code.

2. Implementing the Main View

Below is the full source code for a Java AI chatbot interface in Vaadin using Spring AI. Everything we need is in the MainView.java class.

@Route("") // Map view to the root URL
class MainView extends VerticalLayout {

    // Chat history for the LLM
    private final ArrayList<Message> chatHistory = new ArrayList<>();

    VerticalLayout messageList = new VerticalLayout();
    Scroller messageScroller = new Scroller(messageList);
    MessageInput messageInput = new MessageInput();


    MainView(StreamingChatClient chatClient) {
        add(messageScroller, messageInput);
        setSizeFull();
        setMargin(false)
        messageScroller.setSizeFull();
        messageInput.setWidthFull();

        // Add system message to help the AI to behave
        chatHistory.add(new SystemMessage("Only if the user asks you about Vaadin, reply in bro style. Always show a piece a code."));

        messageInput.addSubmitListener(ev -> {

            // Add user input as markdown message
            chatHistory.add(new UserMessage(ev.getValue()));
            messageList.add(new MarkdownMessage(ev.getValue(),"Me"));

            // Placeholder message for the upcoming AI reply
            MarkdownMessage reply = new MarkdownMessage("Assistant");
            messageList.add(reply);

            // Ask AI and stream back the reply to UI
            Prompt prompt = new Prompt(chatHistory);
            chatClient.stream(prompt)
                    .doOnComplete(() -> chatHistory.add(new AssistantMessage(reply.getMarkdown())))
                    .subscribe(cr -> reply.appendMarkdownAsync(cr.getResult().getOutput().getContent()));
            reply.scrollIntoView();
        });
    }
 }

3. Enabling real-time AI responses

This already works, but chat streaming is not that useful to the user if it is not available in real-time. Enable WebSockets for real-time client-server communication by adding @Push to your Spring Boot application class:

@SpringBootApplication
@Push
public class DemoApplication implements AppShellConfigurator {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

What happens here? 

  • UI components: We have a VerticalLayout, Scroller, and MessageInput to create a simple scrolling chat interface. The Scroller ensures that the messages are visible.
  • Chat history: We maintain a history of messages using an ArrayList. This (user-based) history is important for the AI to generate contextually relevant responses. Otherwise, it has no memory and only responds to the latest input.
  • AI integration: The StreamingChatClient streams the user's prompt to the AI, and the response is dynamically added to the chat and streamed to the client token by token. 
  • WebSockets: Vaadin automatically manages the state and updates the UI components in the browser; you do not need to do anything else but enable it. If WebSockets are unavailable, Vaadin will gracefully fall back to using long polling.

4. Running your Java AI application

Run your Spring Boot application using:

mvn spring-boot:run

or execute it from your IDE using DemoApplication.

You should see a fully functional AI-powered chat interface, where you can type messages and receive AI-generated responses in real time. This setup's simplicity allows you to focus on expanding and refining your application's capabilities.

5. Deploying to the cloud

To deploy your Java AI application, create a Dockerfile and deploy it to cloud platforms like Fly.io or Google Cloud.

Add more features

By combining Vaadin Flow and Spring AI, you can create powerful, interactive applications with minimal effort. This example serves as a starting point, and the possibilities are endless.

Potential use cases include:

Learn more

Find the full source code in GitHubFor more details on Java AI applications, check out these resources:

Happy Java coding!

Sami Ekblad
Sami Ekblad
Sami Ekblad is one of the original members of the Vaadin team. As a DX lead he is now working as a developer advocate, to help people the most out of Vaadin tools. You can find many add-ons and code samples to help you get started with Vaadin. Follow at – @samiekblad
Other posts by Sami Ekblad