本文目录导读:

我将为您提供一个完整的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的核心功能,包括:
- 聊天对话:支持简单对话和带上下文的对话
- 代码生成:根据描述生成指定语言的代码
- 文本分析:情感分析、关键词提取等
- 图片相关:生成图片描述和实际图片
- 多轮对话:支持连续的对话管理
- 错误处理:完善的异常处理和响应
您可以根据实际需求扩展更多功能,如流式输出、本地模型支持、向量数据库集成等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播