×
Community Blog Quickly Build Java Applications Based on Open-source Framework Spring AI Alibaba

Quickly Build Java Applications Based on Open-source Framework Spring AI Alibaba

This article aims to help developers quickly master and apply Spring AI Alibaba to improve the efficiency and security of Java-based large model application development.

By Shenxun

1

Introduction to Spring AI

When Java calls large models, it often lacks an efficient and unified application framework. Spring, as a well-known Java application framework provider, has launched Spring AI to solve this problem. It draws on some core concepts of LangChain and combines the advantages of object-oriented programming in Java. The core advantage of Spring AI is that it provides a unified interface standard, enabling developers to easily switch between different AI service providers, such as OpenAI and Alibaba Cloud, by writing code once. In addition, Spring AI supports streaming output compatibility and automatic POJO mapping, greatly simplifying the development process. Moreover, it is maintained by a dedicated team, so long-term stability and security are ensured. This design facilitates Java-based large model application development and improves efficiency.

Introduction to Spring AI Alibaba

When large models are applied in China, the main challenge is to meet the intelligence level required by the business while ensuring content moderation. As an ideal solution in this context, Spring AI Alibaba provides strong content moderation assurance. It is based on the Qwen-2.5 model, which was rated top in the open-source field in the OpenCompass evaluation. Spring AI Alibaba is created by combining Alibaba Cloud best practices with the localization of the Spring AI framework. It not only simplifies the process of connecting developers to different AI services but also streamlines migration and adaptation through a unified interface standard. Its core advantages include support for a variety of generative tasks (such as dialogues and text-based image generation), compatibility with the Flux stream processing mechanism, and provision of features such as Prompt Template and OutputParser, which greatly improves development efficiency and flexibility. In addition, Spring AI Alibaba also can call external data, allowing users to customize and expand AI functions based on their needs, consolidating the foundation for building more intelligent applications.

Spring AI Alibaba Practice: Backend Construction

To build a project that supports the prompt stream return interface after integrating Spring AI Alibaba based on the Spring Boot and completing a simple dialogue model, and ensure that the GET interface supports cross-origin resource sharing (CORS), we can follow the following steps. This section will guide in detail how to configure and write code to achieve this goal.

1. Confirm the Development Environment

• Make sure your JDK version is JDK 17 and later.

• Use Spring Boot 3.3.x or later.

2. Apply for an API Key in Alibaba Cloud

• Visit the Alibaba Cloud Model Studio page and log on to your account.

• Activate the Model Studio Large Model Inference service to obtain the API key.

• Configure environment variables:

export AI_DASHSCOPE_API_KEY=your API_KEY or set it directly in the application configuration file.

3. Add Repositories and Dependencies

As the current version of Spring AI has not been committed to the official Maven repository, you need to add additional repositories to access these resources:

<repositories>
    <repository>
      <id>sonatype-snapshots</id>

      <url>https://oss.sonatype.org/content/repositories/snapshots</url>

      <snapshots>
        <enabled>true</enabled>

      </snapshots>

    </repository>

    <repository>
      <id>spring-milestones</id>

      <name>Spring Milestones</name>

      <url>https://repo.spring.io/milestone</url>

      <snapshots>
        <enabled>false</enabled>

      </snapshots>

    </repository>

    <repository>
      <id>spring-snapshots</id>

      <name>Spring Snapshots</name>

      <url>https://repo.spring.io/snapshot</url>

      <releases>
        <enabled>false</enabled>

      </releases>

    </repository>

</repositories>

Next, add dependencies on the spring-ai-alibaba-starter and Spring Boot parent projects in pom.xml:

<parent>
  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-starter-parent</artifactId>

  <version>3.3.4</version>

  <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
  <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>

    <artifactId>spring-ai-alibaba-starter</artifactId>

    <version>1.0.0-M2.1</version>

  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-webflux</artifactId>

  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-data-jpa</artifactId>

  </dependency>

  <!-- Other dependencies that may be required... -->
</dependencies>

Note that spring-boot-starter-webflux is included here because it is essential for processing responsive streams (Flux).

4. Configure application.properties

In the project's src/main/resources/application.properties file, add the following configuration:

spring.ai.dashscope.api-key=${AI_DASHSCOPE_API_KEY}

5. Write a Controller

Create a new controller class ChatController.java to implement a CORS-enabled chat interface that accepts input parameters and uses the ChatClient to send requests to the AI model, while leveraging PromptTemplate to provide a richer interactive experience. In addition, this controller will use the functionality provided by the WebFlux framework to return the reactive type Flux<String>.

import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/ai")
@CrossOrigin(origins = "*") // Support cross-origin requests from all sources.
public class ChatController {

    private final ChatClient chatClient;
    @Value("classpath:your-prompt-template.st")
    Resource promptTemplateResource;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    @GetMapping("/steamChat")
    public Flux<String> steamChat(@RequestParam String input) {
        PromptTemplate promptTemplate = new PromptTemplate(promptTemplateResource);
        Prompt prompt = promptTemplate.create(Map.of("input", input));
        return chatClient.prompt(prompt).stream().content();
    }
}

Make sure that your-prompt-template.st is a template file located in the src/main/resources/ that defines the specific prompt text format used when interacting with the AI. For example:

Response to {input}. 

Through the above steps, you have integrated Spring AI Alibaba based on Spring Boot and realized the functions that meet the requirements of the topic. This process covers all the key points from preparing the environment to the final coding, including support for external libraries, enabling specific features, and designing REST APIs.

Building of a Matching Chat Front-end Application

Based on what I know, we will adopt the React framework to create a simple chat application. The application interacts with the backend through HTTP requests and supports receiving streaming data (flux<String>) from the backend.

1. Initialize the React Project

First, make sure you have Node.js and NPM or YARN installed on your machine. Then run the following command to create a new React application:

npx create-react-app frontend
cd frontend
npm install

This will create a basic React project called frontend and automatically install all the dependencies needed to run it.

2. Modify the Basic File Structure

Adjust the contents of the basic file as required. The main focus here is on the HTML template, the main entry file, and the core components.

public/index.html

Keep the default. This file defines the basic structure of the web page.

src/index.js

No modification. The default configuration is sufficient for the current example.

src/App.js

This file is responsible for rendering the root component. We will import and display the custom ChatComponent.

import React from 'react';
import ChatComponent from './components/ChatComponent';

function App() {
  return (
    <div className="App">
      <ChatComponent />
    </div>

  );
}

export default App;

src/components/ChatComponent.js

This is the main part where we implement the user interface logic, including the input box, the send button, and the area to display messages. We will also handle the process of sending requests to the server and listening to the response stream here.

import React, { useState } from 'react';

const ChatComponent = () => {
  const [input, setInput] = useState('');
  const [messages, setMessages] = useState('');

  const handleInputChange = (event) => {
    setInput(event.target.value);
  };

  const handleSendMessage = async () => {
    if (!input.trim()) return; // Avoid empty messages.
    try {
      const response = await fetch(`http://localhost:8080/ai/steamChat?input=${encodeURIComponent(input)}`, { method: 'GET' });
      if (!response.ok) throw new Error('Network response was not ok');
      
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let done = false;

      while (!done) {
        const { value, done: readerDone } = await reader.read();
        done = readerDone;
        const chunk = decoder.decode(value, { stream: true });
        setMessages((prevMessages) => prevMessages + chunk);
      }

      // Add a delimiter to distinguish messages in different rounds.
      setMessages((prevMessages) => prevMessages + '\n\n=============================\n\n');
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setInput('');  // Clear a field.
    }
  };

  const handleClearMessages = () => {
    setMessages('');
  };

  return (
    <div>
      <input type="text" value={input} onChange={handleInputChange} placeholder="Enter your message" />
      <button onClick={handleSendMessage}>Send</button>

      <button onClick={handleClearMessages}>Clear</button>

      <div>
        <h3>Messages:</h3>

        <pre>{messages}</pre>

      </div>

    </div>

  );
};

export default ChatComponent;

In the above code, we use fetch API to initiate a GET request to the specified URL and use ReadableStream to read the data stream returned by the server. The message list on the page is updated each time a new data block is received. In addition, it also includes a feature to clear message records.

3. Run the Project

After completing the above steps, you can start the front-end service to view the effect:

npm start

This command enables the development server locally, with the default access address of http://localhost:3000. Opening your browser to enter the address, you will see a simple chat interface where you can send and receive messages in real time.

Note:

• Ensure that the backend service is running on http://localhost:8080 and can correctly respond to requests in the /ai/steamChat path.

• If you encounter cross-origin resource sharing (CORS) issues, check whether the backend has support for requests from the front-end domain name.


Disclaimer: The views expressed herein are for reference only and don't necessarily represent the official views of Alibaba Cloud.

0 1 0
Share on

Alibaba Cloud Community

1,133 posts | 351 followers

You may also like

Comments