初始化后端项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.5</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.1</spring-ai.version>
</properties>
<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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tika-document-reader</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>1.0.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
spring:
ai:
dashscope:
agent:
app-id: ${APP_ID}
api-key: ${DASHSCOPE_API_KEY}
编写代码
@RestController
@RequestMapping("/chat")
@RequiredArgsConstructor
public class AiChatController {
private final ChatService chatService;
@PostMapping("/simple")
public CommonResponse<ChatResponse> simpleChat(@RequestBody ChatRequest chatRequest) {
return CommonResponse.success(chatService.chat(chatRequest));
}
}
----
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatService {
private final ChatClient dashScopeChatClient;
private final ChatSessionService chatSessionService;
public ChatResponse chat(ChatRequest chatRequest) {
String text = chatRequest.getText();
String sessionId = chatRequest.getSessionId();
CustomUserDetails userDetails = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (StringUtils.isBlank(sessionId)) {
sessionId = UUID.randomUUID().toString();
chatSessionService.createChatSessionRecord(sessionId, userDetails.getUserId());
}
String content = dashScopeChatClient.prompt().user(text).call().content();
String finalSessionId = sessionId;
CompletableFuture.runAsync(() -> {
chatSessionService.createSessionDetail(finalSessionId, SubjectType.USER.name(), text);
chatSessionService.createSessionDetail(finalSessionId, SubjectType.ROBOT.name(), content);
});
return new ChatResponse(finalSessionId, content);
}
}
@PostMapping
public SseEmitter streamChat(@RequestBody ChatRequest chatRequest) throws Exception {
return chatService.streamChat(chatRequest);
}
public SseEmitter streamChat(ChatRequest chatRequest) throws Exception {
SseEmitter finalSseEmitter = new SseEmitter(5l * 60 * 1000);
dashScopeChatClient
.prompt()
.user(chatRequest.getText())
.stream()
.chatClientResponse()
.subscribe(it -> {
String text = it.chatResponse().getResult().getOutput().getText();
log.info("sessionId: {}, text: {}", sessionId, text);
try {
finalSseEmitter.send(text, MediaType.TEXT_EVENT_STREAM);
} catch (IOException e) {
throw new RuntimeException(e);
}
},
e -> {
log.info("session id: {}, occur error", sessionId, e);
},
finalSseEmitter::complete
);
return sseEmitter;
}
效果展示

