跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

OnlyOffice 私有化部署与 Spring Boot 整合实战教程

在 Windows 11 环境下通过 Docker 私有化部署 OnlyOffice Document Server,并结合 Spring Boot 实现文档预览与编辑功能。流程包括镜像拉取、容器参数配置、Java 后端接口开发、前端 SDK 集成及常见问题排查,重点解决跨域访问、回调保存及网络连通性问题,提供可直接运行的代码示例与测试步骤。

CoderByte发布于 2026/2/7更新于 2026/10/25107 浏览
OnlyOffice 私有化部署与 Spring Boot 整合实战教程

OnlyOffice 私有化部署(Win11 + Docker)+ Java 对接全流程教程

一、环境前提

  1. Win11 已安装 Docker Desktop(需确保 Docker 服务正常运行,可通过 docker -v 验证)
  2. 网络通畅(需拉取 OnlyOffice 镜像)
  3. JDK 8+(Java 对接用)、Maven(可选,管理依赖)
  4. 端口说明:OnlyOffice 默认占用 80/443,本次用 9999 映射(避免端口冲突)

二、OnlyOffice Docker 部署(核心步骤)

步骤 1:拉取最新版 OnlyOffice 镜像

打开 Win11 的「终端」(管理员模式),执行以下命令拉取官方最新镜像:

# 拉取 OnlyOffice Document Server 最新版镜像
docker pull onlyoffice/documentserver:latest 
  • 验证拉取结果:执行 docker images,能看到 onlyoffice/documentserver 镜像即成功。
步骤 2:创建本地挂载目录(持久化数据)

为了避免容器重启后数据丢失,创建本地目录映射容器内数据目录:

# 新建本地目录(建议放在非系统盘,比如 D 盘)
mkdir D:\onlyoffice\data
mkdir D:\onlyoffice\logs
mkdir D:\onlyoffice\plugins
mkdir D:\onlyoffice\fonts 
步骤 3:运行 OnlyOffice 容器(忽略 Token 验证)

核心命令:关闭 JWT 验证(忽略 token),并映射端口和目录:

docker run -itd --name onlyoffice \
-p 9999:80 \
-v D:\onlyoffice\data:/var/www/onlyoffice/Data \
-v D:\onlyoffice\logs:/var/log/onlyoffice \
-v D:\onlyoffice\plugins:/var/www/onlyoffice/documentserver/sdkjs-plugins \
-v D:\onlyoffice\fonts:/usr/share/fonts \
-e JWT_SECRET=mysecret \
-e JWT_ENABLED=false \
--restart=always \
onlyoffice/documentserver:latest

参数说明:

  • -p 9999:80:将容器 80 端口映射到主机 9999 端口(访问用)
  • -v:目录挂载(数据/日志/插件/字体持久化)
  • JWT_ENABLED=false:关键!关闭 Token 验证(忽略 JWT)
  • --restart=always:Docker 重启后自动启动容器

--name onlyoffice:给容器命名,方便管理

步骤 4:验证 OnlyOffice 是否启动成功
  • 若状态异常,执行 docker logs onlyoffice 查看报错(常见问题:端口被占用,换 -p 9998:80 重试)。
  • 进阶验证:访问 http://localhost:9999/healthcheck,返回 即服务正常。
{"status":"true"}

浏览器访问验证:打开 http://localhost:9999,若看到 OnlyOffice 欢迎页(显示 Document Server is running),则部署成功!

查看容器状态:执行 docker ps,若 onlyoffice 状态为 Up 则运行中;

步骤 5:解决启动慢/依赖缺失问题(Win11 常见)

OnlyOffice 启动需要下载依赖,Win11 可能出现启动超时:

  1. 执行 docker exec -it onlyoffice bash 进入容器;

退出容器:exit

手动执行初始化脚本:

supervisorctl restart all 

三、Java 对接 OnlyOffice 实现简单实例

核心逻辑

Java 后端提供「文档预览/编辑」接口,返回 OnlyOffice 所需的配置参数(文档地址、回调地址等),前端通过 OnlyOffice SDK 加载编辑器。

步骤 1:创建 Spring Boot 项目(Maven)
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>2.7.0</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>onlyoffice-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!-- Spring Web 核心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 跨域支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <!-- JSON 工具 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
步骤 2:配置文件(application.yml)
server:
  port: 48083 # Java 服务端口
# OnlyOffice 配置
onlyOffice:
  server:
    url: http://localhost:9999 # 本地 Docker 部署的 OnlyOffice 地址
  document:
    storage: D:/onlyoffice/documents/ # 本地文档存储目录(需提前创建)
步骤 3:核心工具类(文档管理)

创建 DocumentUtils.java,处理文档路径、URL 生成:

package com.example.onlyofficedemo.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Component
public class OnlyOfficeUtils {
    @Value("${onlyoffice.document.storage}")
    private String documentStoragePath;

    @Value("${onlyoffice.server.url}")
    private String onlyOfficeServerUrl;

    @Value("${server.port}")
    private String serverPort;

    // 初始化文档存储目录
    public void initStorageDir() {
        File dir = new File(documentStoragePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    // 获取文档访问 URL(供 OnlyOffice 访问)
    public String getDocumentUrl(String fileName) {
        // 本地 Java 服务的 IP + 端口(Win11 需替换为实际 IP,不能用 localhost,否则容器访问不到)
        String host = "http://" + getLocalIp() + ":" + serverPort;
        return host + "/document/get?fileName=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8);
    }

    // 获取回调 URL(OnlyOffice 保存文档时回调)
    public String getCallbackUrl(String fileName) {
        String host = "http://" + getLocalIp() + ":" + serverPort;
        return host + "/document/callback?fileName=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8);
    }

    // 获取 OnlyOffice 编辑器配置 URL
    public String getEditorUrl() {
        return onlyOfficeServerUrl + "/web-apps/apps/api/documents/api.js";
    }

    // 获取本地 IP(关键:容器需访问主机 IP,不能用 localhost)
    private String getLocalIp() {
        try {
            java.net.InetAddress addr = java.net.InetAddress.getLocalHost();
            return addr.getHostAddress();
        } catch (Exception e) {
            return "127.0.0.1";
        }
    }

    // 获取文档本地路径
    public String getDocumentLocalPath(String fileName) {
        return documentStoragePath + File.separator + fileName;
    }
}
步骤 4:Controller 层(核心接口)

创建 OnlyOfficeOffController.java,提供「文档获取、编辑配置、回调保存」接口:

package com.vintechhk.module.document.controller.app.document;

import com.alibaba.fastjson.JSONObject;
import com.vintechhk.module.document.util.OnlyOfficeUtils;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;

/**
 * 用户端 - 协作文档 Controller
 */
@Tag(name = "用户端 - 在线文档")
@RestController
@RequestMapping("/doc/only-office")
@Validated
@Slf4j
@CrossOrigin(origins = "*") // 允许跨域(测试用,生产需限制)
public class OnlyOfficeOffController {

    @Autowired
    private OnlyOfficeUtils onlyOfficeUtils;

    // 初始化:创建测试文档
    @GetMapping("/init")
    public String initTestDocument() {
        log.info("-----------------------初始化---init-------1-----------");
        onlyOfficeUtils.initStorageDir();
        // 创建一个测试 Word 文档(若没有则新建)
        String testFileName = "test-" + UUID.randomUUID() + ".docx";
        String localPath = onlyOfficeUtils.getDocumentLocalPath(testFileName);
        File testFile = new File(localPath);
        if (!testFile.exists()) {
            try {
                testFile.createNewFile();
                // 写入测试内容
                FileOutputStream fos = new FileOutputStream(testFile);
                fos.write("OnlyOffice Java 对接测试文档".getBytes());
                fos.close();
            } catch (Exception e) {
                return "初始化失败:" + e.getMessage();
            }
        }
        log.info("-----------------------初始化---init------2------------");
        return "测试文档创建成功!文件名:" + testFileName + ",访问编辑页:http://localhost:48083/document/edit?fileName=" + testFileName;
    }

    // 获取文档(供 OnlyOffice 访问)
    @GetMapping("/get")
    public ResponseEntity<FileSystemResource> getDocument(@RequestParam String fileName) {
        String localPath = onlyOfficeUtils.getDocumentLocalPath(fileName);
        File file = new File(localPath);
        if (!file.exists()) {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + fileName);
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.APPLICATION_OCTET_STREAM).body(new FileSystemResource(file));
    }

    // 获取 OnlyOffice 编辑配置
    @GetMapping("/edit")
    public JSONObject getEditConfig(@RequestParam String fileName) {
        JSONObject config = new JSONObject();
        // 基础配置
        config.put("documentType", "text"); // 文档类型:text(Word)/spreadsheet(Excel)/presentation(PowerPoint)
        config.put("editorUrl", onlyOfficeUtils.getEditorUrl());
        // 文档配置
        JSONObject document = new JSONObject();
        document.put("title", fileName);
        document.put("url", onlyOfficeUtils.getDocumentUrl(fileName)); // 文档访问 URL
        document.put("fileType", fileName.substring(fileName.lastIndexOf(".") + 1)); // 文件后缀
        document.put("key", UUID.randomUUID().toString()); // 唯一标识(避免缓存)
        config.put("document", document);
        // 编辑器配置
        JSONObject editorConfig = new JSONObject();
        editorConfig.put("callbackUrl", onlyOfficeUtils.getCallbackUrl(fileName)); // 回调地址
        editorConfig.put("lang", "zh-CN"); // 中文
        config.put("editorConfig", editorConfig);
        return config;
    }

    // OnlyOffice 回调保存文档
    @PostMapping("/callback")
    public String callback(HttpServletRequest request, @RequestParam String fileName) {
        try {
            // 解析回调参数
            JSONObject json = JSONObject.parseObject(request.getInputStream(), "UTF-8".getClass());
            String status = json.getString("status"); // status=2 表示文档编辑完成,需要保存
            if ("2".equals(status)) {
                String downloadUrl = json.getJSONObject("url").getString("url");
                // 下载 OnlyOffice 编辑后的文档
                URL url = new URL(downloadUrl);
                URLConnection conn = url.openConnection();
                InputStream is = conn.getInputStream();
                // 覆盖本地文档
                String localPath = onlyOfficeUtils.getDocumentLocalPath(fileName);
                FileOutputStream fos = new FileOutputStream(localPath);
                byte[] buffer = new byte[1024];
                int len;
                while ((len = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
                is.close();
            }
            // 返回 OnlyOffice 要求的格式(必须返回 {"error":0})
            return "{\"error\":0}";
        } catch (Exception e) {
            return "{\"error\":1,\"message\":\"" + e.getMessage() + "\"}";
        }
    }
}
步骤 5:启动类

创建 OnlyOfficeDemoApplication.java:

package com.example.onlyofficedemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OnlyOfficeDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(OnlyOfficeDemoApplication.class, args);
    }
}
步骤 6:前端页面(编辑页)

在 resources/static 目录下创建 edit.html(Spring Boot 静态资源目录):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>OnlyOffice 编辑测试</title>
    <style>
        #editor { width: 100%; height: 800px; }
    </style>
</head>
<body>
<div id="editor"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
    // 获取 URL 参数
    function getUrlParam(name) {
        let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        let r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]);
        return null;
    }
    let fileName = getUrlParam("fileName");
    // 请求 Java 后端获取编辑配置
    $.get("/document/edit?fileName=" + fileName, function(data) {
        // 加载 OnlyOffice 编辑器
        let script = document.createElement('script');
        script.src = data.editorUrl;
        script.onload = function() {
            new DocsAPI.DocEditor("editor", {
                document: data.document,
                documentType: data.documentType,
                editorConfig: data.editorConfig,
                width: "100%",
                height: "100%"
            });
        };
        document.body.appendChild(script);
    });
</script>
</body>
</html>

四、全流程测试

步骤 1:启动服务
  1. 确保 Docker 中的 OnlyOffice 容器运行(docker start onlyoffice);
  2. 启动 Spring Boot 项目(运行 OnlyOfficeDemoApplication.java);
  3. 提前创建 D:/onlyoffice/documents/ 目录(文档存储用)。
步骤 2:初始化测试文档

浏览器访问:http://localhost:48083/document/init

返回类似:测试文档创建成功!文件名:test-xxx.docx,访问编辑页:http://localhost:48083/document/edit?fileName=test-xxx.docx

步骤 3:访问编辑页

复制返回的编辑页 URL 到浏览器打开,即可看到 OnlyOffice 编辑器加载完成,显示测试文档:

  • 可编辑文档内容(如输入「测试 OnlyOffice 保存功能」);
  • 关闭编辑器/点击保存,OnlyOffice 会回调 http://localhost:48083/document/callback 接口,将编辑后的内容保存到本地文档。
步骤 4:验证保存结果

打开 D:/onlyoffice/documents/ 下的测试文档,查看内容是否已更新,确认保存成功。

五、常见问题解决

1. OnlyOffice 无法加载文档
  • 原因:Java 服务的 IP 用了 localhost,容器内无法访问主机的 localhost;
  • 解决:DocumentUtils.java 中 getLocalIp() 需返回 Win11 实际 IP(如 192.168.1.100),而非 127.0.0.1。
2. 容器启动后访问 8080 端口超时
  • 原因:OnlyOffice 启动需要下载依赖,Win11 网络慢;
  • 解决:执行 docker exec -it onlyoffice bash 进入容器,运行 apt update && apt install -y wget,再重启容器。
3. 回调保存失败
  • 原因:OnlyOffice 容器无法访问 Java 服务的回调地址;
  • 解决:确保 Java 服务的端口(9000)未被防火墙拦截,且回调地址用主机实际 IP。
4. 编辑器显示乱码
  • 原因:文档编码问题;
  • 解决:Java 写入文档时用 UTF-8 编码,前端页面指定 <meta charset="UTF-8">。

六、总结

  1. Docker 部署核心:关闭 JWT 验证(JWT_ENABLED=false),映射端口和目录;
  2. Java 对接核心:提供「文档访问 URL」和「回调保存 URL」,且 URL 需用主机实际 IP;
  3. 测试流程:初始化文档 → 访问编辑页 → 编辑保存 → 验证本地文档更新。

至此,从 OnlyOffice 私有化部署到 Java 对接测试的全流程已完成,可基于此扩展更多功能(如文档权限控制、多格式支持、历史版本等)。

目录

  1. OnlyOffice 私有化部署(Win11 + Docker)+ Java 对接全流程教程
  2. 一、环境前提
  3. 二、OnlyOffice Docker 部署(核心步骤)
  4. 步骤 1:拉取最新版 OnlyOffice 镜像
  5. 拉取 OnlyOffice Document Server 最新版镜像
  6. 步骤 2:创建本地挂载目录(持久化数据)
  7. 新建本地目录(建议放在非系统盘,比如 D 盘)
  8. 步骤 3:运行 OnlyOffice 容器(忽略 Token 验证)
  9. 步骤 4:验证 OnlyOffice 是否启动成功
  10. 步骤 5:解决启动慢/依赖缺失问题(Win11 常见)
  11. 三、Java 对接 OnlyOffice 实现简单实例
  12. 核心逻辑
  13. 步骤 1:创建 Spring Boot 项目(Maven)
  14. pom.xml 依赖(核心)
  15. 步骤 2:配置文件(application.yml)
  16. OnlyOffice 配置
  17. 步骤 3:核心工具类(文档管理)
  18. 步骤 4:Controller 层(核心接口)
  19. 步骤 5:启动类
  20. 步骤 6:前端页面(编辑页)
  21. 四、全流程测试
  22. 步骤 1:启动服务
  23. 步骤 2:初始化测试文档
  24. 步骤 3:访问编辑页
  25. 步骤 4:验证保存结果
  26. 五、常见问题解决
  27. 1. OnlyOffice 无法加载文档
  28. 2. 容器启动后访问 8080 端口超时
  29. 3. 回调保存失败
  30. 4. 编辑器显示乱码
  31. 六、总结

更多推荐文章

查看全部
  • 基于 SSM 框架的校园二手物品交易网站设计与实现
  • 智驾后融合感知核心:融合策略设计与量产落地框架
  • 深入理解 LLM Agent:核心概念、架构与发展趋势
  • Python AI 大模型部署实战:本地运行、API 服务与 Docker 封装
  • 大模型分布式训练与高效调参实战
  • Linux lsof 命令常用用法与实战指南
  • AIGC 时代下的模型上下文协议 MCP 详解
  • FPGA 电源系统设计及器件选型指南
  • Windows Terminal 1.0 正式版发布,支持多配置文件与 GPU 加速
  • GitHub Copilot 实战:AI 辅助编程效率提升指南
  • 数据结构与算法:深入理解希尔排序
  • 数据结构:单向链表,顺序栈和链式栈
  • 飞书 CLI 开源指南:AI 接管办公全流程实操
  • LangChain 结合 AI 大模型开发实战指南
  • 论文 AI 检测率高如何免费降低?实用方案汇总
  • XGBoost 机器学习核心原理与实战指南
  • Z-Image-Turbo 快速生成孙珍妮风格人像指南
  • Neo4j Desktop 2 安装与图数据库实战指南
  • OpenWebUI 集成 SearXNG 实现本地大模型联网搜索配置指南
  • Qt与Web混合编程:CEF与QCefView深度解析

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online