别再纸上谈兵了!手把手教你在 Spring Boot 中落地 OpenClaw(Java 实战)

Written by

in

文章目录
  • 很多人在聊 AI Agent、工具调用、模型编排时,讨论得天花乱坠,但一落地就卡在一个现实问题上: “Java 后端到底该怎么接一个真正可控的 AI Agent?” OpenClaw 的价值就在这里——它不是一个 SDK,也不是某个厂商强绑定的 API,而是一个你可以自己部署、自己控制、模型随时可换的本地 AI Agent 网关。 这篇文章不讲概念、不画大饼,直接从 OpenClaw + Spring Boot 的真实集成出发,带你完成: 本地 / VPS 部署 OpenClaw Spring Boot 中把它当作“普通 REST 服务”使用 构建干净、可维护、可扩展的 Java 调用层 对外暴露统一的 AI 接口,供前端或其他系统使用
  • 目录
    • AI Agent 不是 PPT 里的架构图
      • Overview:OpenClaw 在系统中的角色
      • 部署并初始化 OpenClaw
      • 安装与启动
      • 关键配置确认
    • 创建 Spring Boot 项目
      •  基础依赖
      • 项目结构
      • 定义 OpenClaw 请求 / 响应模型
      • Message
      • OpenClawRequest​​​​​​​
      • OpenClawResponse​​​​​​​
      • 使用 RestClient 调用 OpenClaw
      • RestClient 配置​​​​​​​
      • Service 封装​​​​​​​
      • 对外暴露统一 AI 接口
      • Streaming / SSE(可选进阶)
      • 程级最佳实践建议
      • 安全
      • 稳定性
      • 模型无感切换
      • 结语:这才是 Java 后端该有的 AI 接入方式

    很多人在聊 AI Agent、工具调用、模型编排时,讨论得天花乱坠,但一落地就卡在一个现实问题上:

    “Java 后端到底该怎么接一个真正可控的 AI Agent?”

    OpenClaw 的价值就在这里——它不是一个 SDK,也不是某个厂商强绑定的 API,而是一个你可以自己部署、自己控制、模型随时可换的本地 AI Agent 网关

    这篇文章不讲概念、不画大饼,直接从 OpenClaw + Spring Boot 的真实集成出发,带你完成:

    • 本地 / VPS 部署 OpenClaw
    • Spring Boot 中把它当作“普通 REST 服务”使用
    • 构建干净、可维护、可扩展的 Java 调用层
    • 对外暴露统一的 AI 接口,供前端或其他系统使用

    OpenClaw 本质上是一个 本地 AI Gateway

    • 自托管(Self-Hosted)
    • 对外暴露 HTTP API
    • 内部可接入 OpenAI / Anthropic / Gemini / OpenRouter 等模型
    • 对调用方来说:就是一个 REST 服务

    常见网关地址示例:

    http://localhost:18789/v1/chat/completions

    在 Spring Boot 里,我们不需要“集成 OpenClaw SDK”,只需要像调用普通微服务一样调用它即可。

    在写 Java 代码之前,先保证 OpenClaw 已经跑起来

    在 Linux / macOS / VPS 上执行官方提供的安装脚本(示意):

    curl -fsSL https://openclaw.ai/install.sh | bash

    然后运行初始化流程:

    openclaw setup

    你需要完成的事情包括:

    • 选择模型提供方(OpenAI / Gemini / Anthropic / OpenRouter)
    • 配置 API Key
    • 确认监听端口(默认 18789)

    通常配置文件位于:

    ~/.openclaw/openclaw.json

    或通过环境变量注入:

    export OPENCLAW_GATEWAY_TOKEN=xxxxx

    你最终需要记住的只有两点:

    • Base URLhttp://localhost:18789
    • Token:用于 Authorization: Bearer xxx

    使用 Spring Boot 3.x,新建项目后引入 Web Starter:

    <dependency>    
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-web</artifactId></dependency><dependency>    
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    /src/main/java
    └── com/icoderoad/ai
        ├── controller
        │   └── OpenClawController.java
        ├── service
        │   └── OpenClawService.java
        ├── config
        │   └── OpenClawConfig.java
        └── model
            ├── OpenClawRequest.java
            ├── OpenClawResponse.java
            └── Message.java

    package com.icoderoad.ai.model; 
     public class Message { 
         private String role;     
     private String content; 
         public Message() {} 
         public Message(String role, String content) 
     {         
     this.role = role;         
     this.content = content;    
     } 
         // getter / setter }

    package com.icoderoad.ai.model; 
     import java.util.List; 
     public class OpenClawRequest 
     { 
         private String model;     
     private List<Message> messages; 
         // getter / setter 
     }

    package com.icoderoad.ai.model;
    public class OpenClawResponse {
        private String id;
        private String model;
        private Choice[] choices;
        public static class Choice {
            private Message message;
            // getter / setter
        }
        // getter / setter
    }

    这样做的好处是:模型返回结构变化时,你只改 DTO,不动业务代码。

    Spring Boot 3 推荐 RestClient,而不是老的 RestTemplate。

    package com.icoderoad.ai.config;
    @Configuration
    public class OpenClawConfig {
        @Bean
        public RestClient openClawRestClient(
                RestClient.Builder builder,
                @Value("${openclaw.base-url}") String baseUrl,
                @Value("${openclaw.auth-token}") String token
        ) {
            return builder
                    .baseUrl(baseUrl)
                    .defaultHeaders(headers -> {
                        headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
                        if (token != null && !token.isEmpty()) {
                            headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
                        }
                    })
                    .build();
        }
    }

    package com.icoderoad.ai.service;
    @Service
    public class OpenClawService {
        private final RestClient restClient;
        public OpenClawService(RestClient restClient) {
            this.restClient = restClient;
        }
        public OpenClawResponse chat(String userInput) {
            OpenClawRequest request = new OpenClawRequest();
            request.setModel("gpt-4o");
            request.setMessages(List.of(
                    new Message("user", userInput)
            ));
            return restClient.post()
                    .uri("/v1/chat/completions")
                    .body(request)
                    .retrieve()
                    .body(OpenClawResponse.class);
        }
    }

    ​​​​

    package com.icoderoad.ai.controller;
    @RestController
    @RequestMapping("/ai")
    public class OpenClawController {
        private final OpenClawService openClawService;
        public OpenClawController(OpenClawService openClawService) {
            this.openClawService = openClawService;
        }
        @PostMapping("/chat")
        public ResponseEntity<String> chat(@RequestBody ChatRequest request) {
            OpenClawResponse response = openClawService.chat(request.getMessage());
            if (response != null &&
                response.getChoices() != null &&
                response.getChoices().length > 0) {
                return ResponseEntity.ok(
                        response.getChoices()[0]
                                .getMessage()
                                .getContent()
                );
            }
            return ResponseEntity.internalServerError()
                    .body("OpenClaw returned empty response");
        }
        public static class ChatRequest {
            private String message;
            // getter / setter
        }
    }

    现在你可以直接:

    POST /ai/chat

    由 Spring Boot → OpenClaw → 模型 完成整条链路。

    如果你要做 类 ChatGPT UI,可以:

    • OpenClaw 使用 stream=true
    • Spring Boot 使用 SseEmitter 或 WebClient

    示意代码:​​​​​​​

    @GetMapping("/stream")
    public SseEmitter stream(@RequestParam String message) {
        SseEmitter emitter = new SseEmitter(30_000L);
        executor.submit(() -> {
            // 使用 WebClient 订阅 OpenClaw 的流式响应
            // 将 token 按段发送给前端
        });
        return emitter;
    }

    • 不要把 OpenClaw 网关直接暴露公网
    • 只允许后端服务访问
    • 或通过 Nginx + 内网访问控制

    • 使用 Resilience4j / Spring Retry
    • 对模型调用做超时、重试、熔断

    OpenClaw 的最大优势之一:

    换模型 ≠ 改代码

    你只需要:

    • 修改 OpenClaw 配置
    • 或替换 model 字段值

    通过 OpenClaw,你获得的是:

    • 一个完全可控的 AI Gateway
    • 一个与模型厂商解耦的调用方式
    • 一个符合微服务思维的 Java 集成方案

    Spring Boot 不需要“追逐 AI 潮流”,只要把 AI 当作 另一个稳定的后端服务,它就能自然融入你的系统架构中。

    真正的 AI 落地,不是写 Demo,而是能跑、能换、能扩展。

    到此这篇关于别再纸上谈兵了!手把手教你在 Spring Boot 中落地 OpenClaw(Java 实战)的文章就介绍到这了,更多相关Spring Boot OpenClaw实战内容请搜索风君子博客以前的文章或继续浏览下面的相关文章,希望大家以后多多支持风君子博客!

    站内搜索