Spring示例项目无法修改磁盘文件名

代码如下

@PostMapping(“/rename”)
@ResponseBody
public String rename(@RequestBody final Rename body) {

    String fileName = body.getFileName();
    HashMap<String, String> meta = new HashMap<>();
    meta.put("title", fileName + "." + body.getFileType());

    try {

        callbackManager.commandRequest("meta", body.getFileKey(), meta);
        return "result ok";
    } catch (Exception e) {
        e.printStackTrace();
        return e.getMessage();
    }
}

@SneakyThrows
public void commandRequest(final String method,
final String key,
final HashMap meta) { // create a command request
String documentCommandUrl = docserviceUrlSite + docserviceUrlCommand;

    URL url = new URL(documentCommandUrl);
    java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();

    HashMap<String, Object> params = new HashMap<String, Object>();
    params.put("c", method);
    params.put("key", key);

    if (meta != null) {
        params.put("meta", meta);
    }

    String headerToken;
    // 检查是否存在密钥
    if (jwtManager.tokenEnabled() && jwtManager.tokenUseForRequest()) {
        Map<String, Object> payloadMap = new HashMap<>();
        payloadMap.put("payload", params);
        headerToken = jwtManager.createToken(payloadMap);

        // 令牌
        connection.setRequestProperty(documentJwtHeader.equals("")
                ? "Authorization" : documentJwtHeader, "Bearer " + headerToken);

        String token = jwtManager.createToken(params);
        params.put("token", token);
    }

    String bodyString = objectMapper.writeValueAsString(params);

    byte[] bodyByte = bodyString.getBytes(StandardCharsets.UTF_8);

    connection.setRequestMethod("POST");
    connection
            .setRequestProperty("Content-Type", "application/json; charset=UTF-8");  // set the Content-Type header
    connection.setDoOutput(true);  // set the doOutput field to true
    connection.connect();

    try (OutputStream os = connection.getOutputStream()) {
        os.write(bodyByte);  // write bytes to the output stream
    }

    InputStream stream = connection.getInputStream();  // get input stream

    if (stream == null) {
        throw new RuntimeException("Could not get an answer");
    }

    String jsonString = serviceConverter.convertStreamToString(stream);  // convert stream to json string
    connection.disconnect();

    JSONObject response = serviceConverter.convertStringToJSON(jsonString);  // convert json string to json object
    // todo: Add errors ENUM
    String responseCode = response.get("error").toString();
    switch (responseCode) {
        case "0":
        case "4":
            break;
        default:
            throw new RuntimeException(response.toJSONString());
    }

}

不知道原因,断点跟踪也是成功的,没有报错

我下载的demo是最新的

您好,
请参考我们的这个指南:重命名文件 - ONLYOFFICE API 文档 并查一下在Test Example页面这个功能是如何实现的,按照这个示例实现 (为了打开Example页面先需要打开documentserver_url/welcome 页面,执行在那里提供的代码,然后Example页面将在documentserver_url/example 地址可访问

您好,我目前运行的是官方提供的最新的spring的demo,这个rename接口没有实现修改文件名吗,我认为这是一个bug

我也运行了官方的example,同样无法修改文件名

curl -X POST
-H “Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoibWV0YSIsIm1ldGEiOnsidGl0bGUiOiIxMjMuZG9jeCJ9LCJrZXkiOiItODA2NDIxNDgzIn0.7Gmr9_4NzdiJqUbcp-SgG-rKxkVbVxlIGKoBfFbLMGs”
-H “Content-Type: application/json; charset=UTF-8”
-d ‘{
“c”: “meta”,
“key”: “1159135097”,
“meta”: {
“title”: “456.pdf”
},
“token”: “eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjIjoibWV0YSIsIm1ldGEiOnsidGl0bGUiOiIxMjMuZG9jeCJ9LCJrZXkiOiItODA2NDIxNDgzIn0.7Gmr9_4NzdiJqUbcp-SgG-rKxkVbVxlIGKoBfFbLMGs”
}’
http://192.168.23.128:9000/coauthoring/CommandService.ashx” 直接模拟命令执行也不行

我上面说您可以在Test Example页面查一下重命名是如何实现的意思是您需要在那里打开编辑器,转到File (文件) → Rename (重命名),然后查看测试示例编辑器的源代码。
您应该根据上面提供的指南实现重命名功能。指南中提到,您还应该在发送命令之前指定 onRequestRename 事件(您上面这样发送命令在测试示例不会有影像),命令需要在您自己的应用程序发送,还应该相应地配置 onMetaChange 事件


如您所说,在点击重命名按钮时已经指定了onRequestRename 事件了,在这个事件中会调用后端的rename接口,在接口中发送的命令,遗憾的是磁盘文件名并没有修改成功,但是编辑器中显示修改了,我这样说您能明白吗?


这是onMetaChange事件,也同样配置了

请说明一下您所提到的磁盘文件名是什么意思?您是指将文件存储在硬盘上吗?文档应存储在 Web 应用程序的存储中,还有,您需要向Document Server提供可访问的url

是的,我的文件存储到磁盘中了,现在是在编辑器上修改文件名时只修改了编辑器上显示的文件名并没有修改磁盘中的文件名,我也做了很多尝试,包括在发送命令后手动修改文件名,但是出现了一个现象就是,编辑器保存的数据没有写入到磁盘中,导致增量数据丢失,其实用户的感觉是已经报错了的。
下面是文档服务的日志:
[2024-08-23T16:03:09.620] [INFO] [localhost] [docId] [userId] nodeJS - commandFromServer start
[2024-08-23T16:03:09.622] [DEBUG] [localhost] [docId] [userId] nodeJS - checkJwt success: decoded = {“c”:“meta”,“meta”:{“title”:“333.docx”},“key”:“1194547168”}
[2024-08-23T16:03:09.622] [DEBUG] [localhost] [1194547168] [userId] nodeJS - commandFromServer: c = meta
[2024-08-23T16:03:09.624] [INFO] [localhost] [1194547168] [userId] nodeJS - commandFromServer end : {“key”:“1194547168”,“error”:0}
[2024-08-23T16:03:09.628] [DEBUG] [localhost] [1194547168] [userId] nodeJS - pubsub message start:{“type”:11,“ctx”:{“tenant”:“localhost”,“docId”:“1194547168”,“userId”:“userId”},“docId”:“1194547168”,“meta”:{“title”:“333.docx”}}
[2024-08-23T16:03:09.628] [DEBUG] [localhost] [1194547168] [userId] nodeJS - sendData: type = meta

它肯定是可以访问的,因为文档服务和客户端在一个服务器上

指南只有解释怎么在编辑器里实现重命名,没有解释怎么在您软件存储实现。这个您需要自己找办法实现

明白您的意思了,自己实现的话遇到一个问题,怎么将内容手动保存下来呢?断点跟踪发现,当文档编辑器关闭时会调用/track接口,然后回调到“SaveCallback”中的handle方法,保存文档数据。代码如下:
@Override
public int handle(final Track body,
final String fileName) { // handle the callback when the saving request is performed
int result = 0;
try {
callbackManager.processSave(body, fileName); // file saving process
} catch (Exception ex) {
ex.printStackTrace();
result = 1;
}

    return result;
}

自己手动回调时,对于“changesurl”、“history”等参数的模拟没有头绪,请您指导。

这是回调接口的参数:
{“filetype”:“docx”,“url”:"http://192.168.23.128:9000/cache/fi

les/data/1890512366_6857/output.docx/output.docx?md5=H53iQJoZUrwWdftOxYDEYA&expires=1724722928&shardkey=1890512366&filename=output.docx",“key”:“1890512366”,“changesurl”:"

http://192.168.23.128:9000/cache/files/data/1890512366_6857/changes.zip/changes.zip?md5=kMbqRKm7dcfmFYLeBwHYAA&expires=1724722928&shardkey=1890512366&filename=changes.zip

",“history”:{“serverVersion”:“8.1.1”,“changes”:[{“created”:“2024-08-27 01:21:34”,“user”:{“id”:“1”,“name”:“John Smith”}}]},“status”:2,“users”:[“1”],“actions”:[{“userid”:"1

",“type”:“edit”}],“lastsave”:“2024-08-27T01:26:44.000Z”,“notmodified”:false}

这些参数我应该怎么获取呢

您好,
为了手动保存可以使用forcesave:保存文件 - ONLYOFFICE API 文档 (比如,可以向Command Service发送forcesave命令)
发送forcesave命令的时候您callback会自动接收这些数据 (“history”, 等): 回调处理程序 - ONLYOFFICE API 文档

您还可以参考这个保存Java代码示例:回调处理程序 - ONLYOFFICE API 文档

或者您说的是”保存为“? 保存为情况下,缓存中文件的链接直接到达客户端浏览器,不发送到callback

感谢您的指导,这就是我想要的,我希望的就是在重命名时先将用户在客户端上未保存的内容手动保存到文档中,然后再调用meta命令修改编辑器上展示的文件名,再修改实际的磁盘上的文件名,这样就完整了。

那么,现在您了解了如何操作,或者您需要更详细地解释哪些特定点?

暂时没有了,再次感谢,我会尝试的。

1 Like