Java Spring AI案例

wen java案例 1

本文目录导读:

Java Spring AI案例

  1. 项目结构
  2. pom.xml 配置
  3. 主应用类
  4. 配置文件 application.yml
  5. AI配置类
  6. AI服务接口
  7. AI服务实现类
  8. 聊天控制器
  9. 图片生成控制器
  10. 测试类
  11. 使用说明

我将为您提供一个完整的Java Spring AI案例,展示如何使用Spring AI框架集成AI功能。

项目结构

spring-ai-demo/
├── pom.xml
├── src/main/java/com/example/springaidemo/
│   ├── SpringAiDemoApplication.java
│   ├── controller/
│   │   ├── ChatController.java
│   │   └── ImageController.java
│   ├── service/
│   │   ├── AIService.java
│   │   └── AIServiceImpl.java
│   └── config/
│       └── AiConfig.java
└── src/main/resources/
    └── application.yml

pom.xml 配置

<?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 
         http://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.2.0</version>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-ai-demo</artifactId>
    <version>1.0.0</version>
    <name>spring-ai-demo</name>
    <description>Spring AI Demo Project</description>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>0.8.1</spring-ai.version>
    </properties>
    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring AI OpenAI -->
        <dependency>
            <groupId>org.springframework.experimental.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <!-- Spring AI Azure OpenAI -->
        <dependency>
            <groupId>org.springframework.experimental.ai</groupId>
            <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

主应用类

package com.example.springaidemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringAiDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringAiDemoApplication.class, args);
    }
}

配置文件 application.yml

server:
  port: 8080
spring:
  application:
    name: spring-ai-demo
  # OpenAI 配置
  ai:
    openai:
      api-key: ${OPENAI_API_KEY:your-api-key-here}
      chat:
        options:
          model: gpt-3.5-turbo
          temperature: 0.7
          max-tokens: 1000
    # Azure OpenAI 配置(可选)
    azure:
      openai:
        endpoint: ${AZURE_OPENAI_ENDPOINT:}
        api-key: ${AZURE_OPENAI_API_KEY:}
        chat:
          options:
            deployment-name: gpt-35-turbo
            temperature: 0.7
            max-tokens: 1000
# 日志配置
logging:
  level:
    com.example: DEBUG
    org.springframework.ai: DEBUG

AI配置类

package com.example.springaidemo.config;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.image.ImageClient;
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.OpenAiImageClient;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiConfig {
    @Value("${spring.ai.openai.api-key}")
    private String openAiApiKey;
    @Bean
    public OpenAiApi openAiApi() {
        return new OpenAiApi(openAiApiKey);
    }
    @Bean
    public ChatClient chatClient(OpenAiApi openAiApi) {
        return new OpenAiChatClient(openAiApi);
    }
    @Bean
    public ImageClient imageClient(OpenAiApi openAiApi) {
        return new OpenAiImageClient(openAiApi);
    }
}

AI服务接口

package com.example.springaidemo.service;
import java.util.List;
import java.util.Map;
public interface AIService {
    /**
     * 发送聊天消息
     */
    String chat(String message);
    /**
     * 带上下文的聊天
     */
    String chatWithContext(String userMessage, String conversationId);
    /**
     * 生成代码
     */
    String generateCode(String description, String language);
    /**
     * 文本分析
     */
    Map<String, Object> analyzeText(String text);
    /**
     * 生成图片描述
     */
    String generateImageDescription(String prompt);
    /**
     * 多轮对话
     */
    List<String> multiTurnChat(List<String> messages);
}

AI服务实现类

package com.example.springaidemo.service.impl;
import com.example.springaidemo.service.AIService;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.system.SystemPromptTemplate;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Service
public class AIServiceImpl implements AIService {
    @Autowired
    private ChatClient chatClient;
    // 存储对话上下文
    private final Map<String, List<Message>> conversationContexts = new ConcurrentHashMap<>();
    @Override
    public String chat(String message) {
        try {
            Prompt prompt = new Prompt(new UserMessage(message));
            ChatResponse response = chatClient.call(prompt);
            return response.getResult().getOutput().getContent();
        } catch (Exception e) {
            return "抱歉,处理您的请求时出现错误: " + e.getMessage();
        }
    }
    @Override
    public String chatWithContext(String userMessage, String conversationId) {
        List<Message> messages = conversationContexts
                .computeIfAbsent(conversationId, k -> new ArrayList<>());
        // 添加用户消息
        messages.add(new UserMessage(userMessage));
        // 保持上下文在合理范围内
        if (messages.size() > 10) {
            messages = messages.subList(messages.size() - 10, messages.size());
        }
        Prompt prompt = new Prompt(messages);
        ChatResponse response = chatClient.call(prompt);
        // 添加AI响应到上下文
        String aiResponse = response.getResult().getOutput().getContent();
        messages.add(new AssistantMessage(aiResponse));
        conversationContexts.put(conversationId, messages);
        return aiResponse;
    }
    @Override
    public String generateCode(String description, String language) {
        String systemPrompt = String.format(
            "你是一个专业的%s程序员,请根据描述生成高质量的代码,包含必要的注释和错误处理。", 
            language
        );
        SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
        Message systemMessage = systemPromptTemplate.createMessage();
        Prompt prompt = new Prompt(List.of(systemMessage, new UserMessage(description)));
        ChatResponse response = chatClient.call(prompt);
        return response.getResult().getOutput().getContent();
    }
    @Override
    public Map<String, Object> analyzeText(String text) {
        String analysisPrompt = """
            请分析以下文本,并以JSON格式返回分析结果,包含:
            1. 情感分析(正面/负面/中性)
            2. 关键词
            3. 文本摘要
            4. 语言风格
            文本:%s
            """.formatted(text);
        Prompt prompt = new Prompt(new UserMessage(analysisPrompt));
        ChatResponse response = chatClient.call(prompt);
        Map<String, Object> result = new HashMap<>();
        result.put("analysis", response.getResult().getOutput().getContent());
        result.put("originalText", text);
        result.put("timestamp", System.currentTimeMillis());
        return result;
    }
    @Override
    public String generateImageDescription(String prompt) {
        String imagePrompt = String.format(
            "请为以下主题生成详细的图片描述,用于AI图片生成:%s\n" +
            "包含:场景、色彩、构图、风格等详细信息", 
            prompt
        );
        Prompt aiPrompt = new Prompt(new UserMessage(imagePrompt));
        ChatResponse response = chatClient.call(aiPrompt);
        return response.getResult().getOutput().getContent();
    }
    @Override
    public List<String> multiTurnChat(List<String> messages) {
        List<Message> chatMessages = new ArrayList<>();
        for (String message : messages) {
            chatMessages.add(new UserMessage(message));
        }
        Prompt prompt = new Prompt(chatMessages);
        ChatResponse response = chatClient.call(prompt);
        List<String> responses = new ArrayList<>();
        responses.add(response.getResult().getOutput().getContent());
        return responses;
    }
}

聊天控制器

package com.example.springaidemo.controller;
import com.example.springaidemo.service.AIService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/ai")
public class ChatController {
    @Autowired
    private AIService aiService;
    /**
     * 简单聊天
     */
    @PostMapping("/chat")
    public ResponseEntity<String> chat(@RequestBody Map<String, String> request) {
        String message = request.get("message");
        if (message == null || message.isEmpty()) {
            return ResponseEntity.badRequest().body("消息不能为空");
        }
        String response = aiService.chat(message);
        return ResponseEntity.ok(response);
    }
    /**
     * 带上下文的对话
     */
    @PostMapping("/chat/context")
    public ResponseEntity<String> chatWithContext(@RequestBody Map<String, String> request) {
        String message = request.get("message");
        String conversationId = request.getOrDefault("conversationId", "default");
        if (message == null || message.isEmpty()) {
            return ResponseEntity.badRequest().body("消息不能为空");
        }
        String response = aiService.chatWithContext(message, conversationId);
        return ResponseEntity.ok(response);
    }
    /**
     * 代码生成
     */
    @PostMapping("/code")
    public ResponseEntity<String> generateCode(@RequestBody Map<String, String> request) {
        String description = request.get("description");
        String language = request.getOrDefault("language", "Java");
        if (description == null || description.isEmpty()) {
            return ResponseEntity.badRequest().body("描述不能为空");
        }
        String code = aiService.generateCode(description, language);
        return ResponseEntity.ok(code);
    }
    /**
     * 文本分析
     */
    @PostMapping("/analyze")
    public ResponseEntity<Map<String, Object>> analyzeText(@RequestBody Map<String, String> request) {
        String text = request.get("text");
        if (text == null || text.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "文本不能为空"));
        }
        Map<String, Object> analysis = aiService.analyzeText(text);
        return ResponseEntity.ok(analysis);
    }
    /**
     * 图片描述生成
     */
    @PostMapping("/image-description")
    public ResponseEntity<String> generateImageDescription(@RequestBody Map<String, String> request) {
        String prompt = request.get("prompt");
        if (prompt == null || prompt.isEmpty()) {
            return ResponseEntity.badRequest().body("提示词不能为空");
        }
        String description = aiService.generateImageDescription(prompt);
        return ResponseEntity.ok(description);
    }
    /**
     * 多轮对话
     */
    @PostMapping("/multi-turn")
    public ResponseEntity<List<String>> multiTurnChat(@RequestBody Map<String, Object> request) {
        @SuppressWarnings("unchecked")
        List<String> messages = (List<String>) request.get("messages");
        if (messages == null || messages.isEmpty()) {
            return ResponseEntity.badRequest().body(List.of("消息列表不能为空"));
        }
        List<String> responses = aiService.multiTurnChat(messages);
        return ResponseEntity.ok(responses);
    }
    /**
     * 健康检查
     */
    @GetMapping("/health")
    public ResponseEntity<String> health() {
        return ResponseEntity.ok("AI Service is running!");
    }
}

图片生成控制器

package com.example.springaidemo.controller;
import org.springframework.ai.image.ImageClient;
import org.springframework.ai.image.ImageGeneration;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/ai/image")
public class ImageController {
    @Autowired
    private ImageClient imageClient;
    /**
     * 生成图片
     */
    @PostMapping("/generate")
    public ResponseEntity<Map<String, Object>> generateImage(@RequestBody Map<String, String> request) {
        String prompt = request.get("prompt");
        String size = request.getOrDefault("size", "1024x1024");
        int n = Integer.parseInt(request.getOrDefault("n", "1"));
        if (prompt == null || prompt.isEmpty()) {
            return ResponseEntity.badRequest().body(Map.of("error", "提示词不能为空"));
        }
        try {
            ImagePrompt imagePrompt = new ImagePrompt(prompt, size, n);
            ImageResponse response = imageClient.call(imagePrompt);
            Map<String, Object> result = Map.of(
                "success", true,
                "images", response.getResults().stream()
                    .map(ImageGeneration::getOutput)
                    .toList()
            );
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            return ResponseEntity.internalServerError()
                .body(Map.of("error", "图片生成失败: " + e.getMessage()));
        }
    }
}

测试类

package com.example.springaidemo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SpringAiDemoApplicationTests {
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void testChatEndpoint() {
        Map<String, String> request = Map.of("message", "你好,请介绍一下你自己");
        ResponseEntity<String> response = restTemplate.postForEntity(
            "/api/ai/chat", 
            request, 
            String.class
        );
        System.out.println("Chat Response: " + response.getBody());
    }
    @Test
    void testCodeGeneration() {
        Map<String, String> request = Map.of(
            "description", "请生成一个Spring Boot的Hello World控制器",
            "language", "Java"
        );
        ResponseEntity<String> response = restTemplate.postForEntity(
            "/api/ai/code", 
            request, 
            String.class
        );
        System.out.println("Generated Code: " + response.getBody());
    }
    @Test
    void testHealthCheck() {
        ResponseEntity<String> response = restTemplate.getForEntity(
            "/api/ai/health", 
            String.class
        );
        System.out.println("Health: " + response.getBody());
    }
}

使用说明

配置API密钥

application.yml 中设置您的OpenAI API密钥:

spring:
  ai:
    openai:
      api-key: your-actual-api-key-here

或者在启动时设置环境变量:

export OPENAI_API_KEY=your-actual-api-key-here

启动应用

mvn spring-boot:run

API测试示例

# 聊天
curl -X POST http://localhost:8080/api/ai/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "请用中文回答:什么是Spring框架?"}'
# 代码生成
curl -X POST http://localhost:8080/api/ai/code \
  -H "Content-Type: application/json" \
  -d '{"description": "创建REST API控制器", "language": "Java"}'
# 文本分析
curl -X POST http://localhost:8080/api/ai/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "今天的天气真好,适合出去散步!"}'
# 带上下文的对话
curl -X POST http://localhost:8080/api/ai/chat/context \
  -H "Content-Type: application/json" \
  -d '{"message": "我的名字是张三", "conversationId": "user123"}'
curl -X POST http://localhost:8080/api/ai/chat/context \
  -H "Content-Type: application/json" \
  -d '{"message": "你还记得我的名字吗?", "conversationId": "user123"}'

这个案例展示了Spring AI的核心功能,包括:

  1. 聊天对话:支持简单对话和带上下文的对话
  2. 代码生成:根据描述生成指定语言的代码
  3. 文本分析:情感分析、关键词提取等
  4. 图片相关:生成图片描述和实际图片
  5. 多轮对话:支持连续的对话管理
  6. 错误处理:完善的异常处理和响应

您可以根据实际需求扩展更多功能,如流式输出、本地模型支持、向量数据库集成等。

上一篇Java RAG案例

下一篇LangChain4j案例

抱歉,评论功能暂时关闭!