Deploy OnlyOffice and Integrate It with Spring Boot & Vue for Word Editing

This guide walks through deploying OnlyOffice (Docker or Ubuntu), configuring the server, adding a Vue front‑end with the OnlyOffice API, building a Spring Boot controller to serve and save documents, handling callbacks, and troubleshooting common issues such as service status, token settings, and proxy configuration.

Java Architect Handbook
Java Architect Handbook
Java Architect Handbook
Deploy OnlyOffice and Integrate It with Spring Boot & Vue for Word Editing

Overview

This guide shows how to deploy OnlyOffice, integrate it with a Vue front‑end and a Spring Boot back‑end, and enable online Word document editing, saving, and downloading.

1. OnlyOffice deployment

OnlyOffice can be installed either via Docker or directly on Ubuntu.

# Docker installation
docker pull onlyoffice/documentserver
docker run -d -p 80:80 onlyoffice/documentserver
# Ubuntu installation
apt-get update && apt-get install -y onlyoffice-documentserver

2. Front‑end integration

Add a placeholder element and load the OnlyOffice JavaScript API. Then create a configuration object that points to the back‑end endpoints.

<div id="placeholder"></div>
<script type="text/javascript" src="https://<em>documentserver</em>/web-apps/apps/api/documents/api.js"></script>
const config = {
  document: {
    mode: 'edit',
    fileType: 'docx',
    key: String(Math.floor(Math.random() * 10000)),
    title: route.query.name + '.docx',
    url: import.meta.env.VITE_APP_API_URL + `/getFile/${route.query.id}`,
    permissions: {
      comment: true,
      download: true,
      modifyContentControl: true,
      modifyFilter: true,
      edit: true,
      fillForms: true,
      review: true
    }
  },
  documentType: 'word',
  editorConfig: {
    user: { id: 'user', name: 'user' },
    customization: { plugins: false, forcesave: true },
    lang: 'en'
  },
  height: '100%',
  width: '100%'
};
new DocsAPI.DocEditor('placeholder', config);

3. Back‑end integration

A Spring Boot controller provides two main endpoints: /getFile/{meeting_id} – reads the meeting‑minute file from the path stored in the database and returns it as a binary stream. /callback – receives OnlyOffice status callbacks; when status == 2 (ready for saving) the document is downloaded from the callback URL and saved locally.

@RestController
public class OnlyOfficeController {
    @Autowired
    private IMeetingTableService meetingTableService;
    private String meetingMinutesFilePath;

    @GetMapping("/getFile/{meeting_id}")
    public ResponseEntity<byte[]> getFile(@PathVariable Long meeting_id) throws IOException {
        MeetingTable meetingTable = meetingTableService.selectMeetingTableById(meeting_id);
        meetingMinutesFilePath = meetingTable.getMeetingMinutesFilePath();
        if (meetingMinutesFilePath == null || meetingMinutesFilePath.isEmpty()) {
            return ResponseEntity.notFound().build();
        }
        File file = new File(meetingMinutesFilePath);
        byte[] data = Files.readAllBytes(file.toPath());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", URLEncoder.encode(file.getName(), "UTF-8"));
        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }

    @PostMapping("/callback")
    public ResponseEntity<Object> handleCallback(@RequestBody CallbackData callbackData) throws IOException {
        if (callbackData.getStatus() == 2) { // ready for saving
            HttpsKitWithProxyAuth.downloadFile(callbackData.getUrl(), meetingMinutesFilePath);
        }
        return ResponseEntity.ok(Collections.singletonMap("error", 0));
    }

    // CallbackData class contains fields required by OnlyOffice callback API (status, url, key, etc.)
}

4. HTTP utility

The HttpsKitWithProxyAuth class wraps Apache HttpClient and supports GET, POST (JSON, form‑urlencoded, multipart), PUT, and file download. It can be configured to use HTTP or SOCKS proxy and includes connection‑pool management.

public class HttpsKitWithProxyAuth {
    private static CloseableHttpClient httpClient;
    private static RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(10000)
        .setSocketTimeout(30000)
        .build();

    public static String get(String url) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("User-Agent", "Mozilla/5.0");
        httpGet.setConfig(requestConfig);
        try (CloseableHttpResponse response = getHttpClient().execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            return entity != null ? EntityUtils.toString(entity) : null;
        } catch (Exception e) {
            // log error
            return null;
        }
    }

    public static void downloadFile(String downloadUrl, String savePath) throws IOException {
        HttpGet httpGet = new HttpGet(downloadUrl);
        httpGet.setHeader("User-Agent", "Mozilla/5.0");
        httpGet.setConfig(requestConfig);
        try (CloseableHttpResponse response = getHttpClient().execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                try (InputStream in = entity.getContent();
                     FileOutputStream out = new FileOutputStream(savePath)) {
                    IOUtils.copy(in, out);
                }
            }
        }
    }

    private static CloseableHttpClient getHttpClient() {
        if (httpClient == null) {
            synchronized (HttpsKitWithProxyAuth.class) {
                if (httpClient == null) {
                    httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
                }
            }
        }
        return httpClient;
    }
    // Additional methods for postJson, postFormUrlencoded, postFormMultipart omitted for brevity
}

5. Common issues and troubleshooting

Check OnlyOffice services are running: systemctl status ds*.

Disable token checks in /etc/onlyoffice/documentserver/local.json and default.json by setting all token.enable fields to false and allowing private IP access:

{
  "token": { "enable": { "request": { "inbox": false, "outbox": false }, "browser": false } },
  "request-filtering-agent": { "allowPrivateIPAddress": true, "allowMetaIPAddress": true },
  "rejectUnauthorized": false
}

Restart the document server after modifying the configuration.

Adjust Spring Security to permit unauthenticated access to /callback, /getFile/*, and static resources (e.g., requests.antMatchers("/callback", "/getFile/*").permitAll()).

If you prefer direct document URLs (e.g., http://host:8089/word/1234.docx), configure an Nginx proxy that maps /word/ to the file location.

6. Example document URL

For quick testing, replace the front‑end url with an online DOCX link, for example:

https://d2nlctn12v279m.cloudfront.net/assets/docs/samples/zh/demo.docx

This URL can be used directly in the config.document.url field to verify that the editor loads and saves correctly.

backendJavaVueSpringBootOnlyOfficeDocumentEditing
Java Architect Handbook
Written by

Java Architect Handbook

Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.