SpringBoot 集成 LangChain4j OpenAI
- [1 依赖](#1 依赖)
- [2 配置](#2 配置)
- [3 代码](#3 代码)
- 
- [1 AiConf.java](#1 AiConf.java)
- [2 ChatController.java](#2 ChatController.java)
- [3 ImageController.java](#3 ImageController.java)
- [4 AudioController.java](#4 AudioController.java)
- [5 Application.java](#5 Application.java)
 
- [4 结果](#4 结果)
1 依赖
        
          
            
            
              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 https://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.5.7</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.xu</groupId>
	<artifactId>langchain-openai</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>langchain-openai</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>25</java.version>
        <maven.compiler.source>25</maven.compiler.source>
        <maven.compiler.target>25</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	</properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-bom</artifactId>
                <version>1.8.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-community-bom</artifactId>
                <version>1.8.0-beta15</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>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
        </dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
			<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>
	<repositories>
		<repository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<releases>
				<enabled>false</enabled>
			</releases>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-snapshots</id>
			<name>Spring Snapshots</name>
			<url>https://repo.spring.io/snapshot</url>
			<releases>
				<enabled>false</enabled>
			</releases>
		</pluginRepository>
	</pluginRepositories>
</project>
         
      2 配置
        
          
            
            
              yml
              复制代码
              
            
          
          server:
  port: 8080
  context-path: /
spring:
  application:
    name: langchain-openai
  servlet:
    multipart:
      max-file-size: 50MB
      max-request-size: 50MB
langchain4j:
  open-ai:
    chat-model:
      api-key: demo
      model-name: gpt-4o-mini
      temperature: 0.7
      base-url: http://*********
      log-requests: true
      log-responses: true
logging:
  level:
    dev.langchain4j: debug
         
      3 代码
1 AiConf.java
        
          
            
            
              java
              复制代码
              
            
          
          package com.xu.conf;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
 * @author hyacinth
 */
@Configuration
public class AiConf {
    @Value("${langchain4j.open-ai.chat-model.api-key}")
    private String apiKey;
    @Value("${langchain4j.open-ai.chat-model.model-name}")
    private String modelName;
    @Value("${langchain4j.open-ai.chat-model.base-url}")
    private String baseUrl;
    @Value("${langchain4j.open-ai.chat-model.log-requests}")
    private boolean logRequests;
    @Value("${langchain4j.open-ai.chat-model.log-responses}")
    private boolean logResponses;
    @Bean
    @Primary
    public OpenAiImageModel openAiImageModel() {
        return OpenAiImageModel.builder()
                .baseUrl(baseUrl)
                .apiKey(apiKey)
                .modelName(modelName)
                .logRequests(true)
                .logResponses(true)
                .build();
    }
    @Bean
    public StreamingChatModel streamingChatModel(){
        return OpenAiStreamingChatModel.builder()
                .baseUrl(baseUrl)
                .apiKey(apiKey)
                .modelName(modelName)
                .logRequests(logRequests)
                .logResponses(logResponses)
                .build();
    }
}
         
      2 ChatController.java
        
          
            
            
              java
              复制代码
              
            
          
          package com.xu.controller;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * 普通聊天
 *
 * @author hyacinth
 */
@Slf4j
@RestController
@RequestMapping("/openai/text")
@AllArgsConstructor
public class ChatController {
    private final ChatModel chatModel;
    private final StreamingChatModel streamingChatModel;
    private final OpenAiChatModel openAiChatModel;
    /**
     * 聊天
     *
     * @param message 问题
     * @return 结果
     */
    @PostMapping("/chat1")
    public Object chat1(@RequestParam(value = "message", defaultValue = "Hello") String message) {
        return chatModel.chat(message);
    }
    /**
     * 聊天
     *
     * @param message 问题
     * @return 结果
     */
    @PostMapping("/chat2")
    public Object chat2(@RequestParam(value = "message", defaultValue = "Hello") String message) {
        var user = UserMessage.from(message);
        var request = ChatRequest.builder().messages(user).build();
        return openAiChatModel.chat(request).aiMessage();
    }
    /**
     * 聊天
     *
     * @param message 问题
     * @return 结果
     */
    @PostMapping("/chat3")
    public Object chat3(@RequestParam(value = "message", defaultValue = "Hello") String message) {
        streamingChatModel.chat(message, new StreamingChatResponseHandler() {
            @Override
            public void onPartialResponse(String partialResponse) {
                log.info("开始: {}", partialResponse);
                IO.println("开始: " + partialResponse);
            }
            @Override
            public void onCompleteResponse(ChatResponse completeResponse) {
                log.info("结束: {}", completeResponse);
            }
            @Override
            public void onError(Throwable error) {
                log.error("异常: {}", error.getMessage());
            }
        });
        return 1;
    }
}
         
      3 ImageController.java
        
          
            
            
              java
              复制代码
              
            
          
          package com.xu.controller;
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiImageModel;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
/**
 * 图片处理
 *
 * @author hyacinth
 */
@RestController
@RequestMapping("/openai/images")
@AllArgsConstructor
public class ImageController {
    private final OpenAiImageModel openAiImageModel;
    private final OpenAiChatModel openAiChatModel;
    /**
     * 生成图片
     *
     * @param message 描述
     * @return 结果
     */
    @PostMapping("/gen1")
    public Object gen1(@RequestParam(value = "message", defaultValue = "生成一个唐老鸭图片") String message) {
        var response = openAiImageModel.generate(message);
        return response.content().base64Data();
    }
    /**
     * 图片识别
     *
     * @param message 描述
     * @param file    图片
     * @return 结果
     * @throws Exception 异常
     */
    @PostMapping("/read")
    public Object read(@RequestParam("message") String message, @RequestParam("file") MultipartFile file) throws Exception {
        var user = UserMessage.from(
                TextContent.from(message),
                ImageContent.from(Base64.getEncoder().encodeToString(file.getBytes()), file.getContentType(), ImageContent.DetailLevel.AUTO)
        );
        var request = ChatRequest.builder().messages(user).build();
        return openAiChatModel.chat(request).aiMessage();
    }
}
         
      4 AudioController.java
        
          
            
            
              java
              复制代码
              
            
          
          package com.xu.controller;
import dev.langchain4j.data.message.AudioContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.openai.OpenAiChatModel;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Base64;
/**
 * 语音处理
 *
 * @author hyacinth
 */
@RestController
@RequestMapping("/openai/audio")
@AllArgsConstructor
public class AudioController {
    private final OpenAiChatModel openAiChatModel;
    /**
     * 语音转文字
     *
     * @param message 描述
     * @param file    予以文件
     * @return 结果
     * @throws Exception 异常
     */
    @PostMapping("/asr1")
    public Object asr1(@RequestParam("message") String message, @RequestParam("file") MultipartFile file) throws Exception {
        var user = UserMessage.from(
                TextContent.from(message),
                AudioContent.from(Base64.getEncoder().encodeToString(file.getBytes()), file.getContentType())
        );
        var request = ChatRequest.builder().messages(user).build();
        return openAiChatModel.chat(request).aiMessage();
    }
}
         
      5 Application.java
        
          
            
            
              java
              复制代码
              
            
          
          package com.xu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * @author hyacinth
 */
@SpringBootApplication
public class Application {
    static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
         
      4 结果
        
          
            
            
              java
              复制代码
              
            
          
            .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.5.7)
2025-10-30T15:55:21.321+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] com.xu.Application                       : Starting Application using Java 25 with PID 29536 (D:\SourceCode\JavaLearn\langchain-openai\target\classes started by hyacinth in D:\SourceCode\JavaLearn\langchain-openai)
2025-10-30T15:55:21.324+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] com.xu.Application                       : No active profile set, falling back to 1 default profile: "default"
2025-10-30T15:55:21.365+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2025-10-30T15:55:21.365+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2025-10-30T15:55:22.155+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2025-10-30T15:55:22.168+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-10-30T15:55:22.169+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.48]
2025-10-30T15:55:22.203+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-10-30T15:55:22.203+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 838 ms
2025-10-30T15:55:22.678+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2025-10-30T15:55:22.694+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2025-10-30T15:55:22.699+08:00  INFO 29536 --- [langchain-openai] [  restartedMain] com.xu.Application                       : Started Application in 1.772 seconds (process running for 2.246)
         
      