You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Java调用Jupyter Server REST API成功上传本地Jupyter笔记本内容

解决Java调用Jupyter Server API上传笔记本内容为空的问题

我之前也碰到过类似的坑,核心是对Jupyter Server API的字段格式要求理解不到位,加上Java处理JSON时的小细节出错导致的。下面给你拆解问题和具体的解决方案:

问题根源分析

你遇到的空文件问题,主要有这几个关键原因:

  1. content字段格式错误:你把JSON字符串转成JSONObject再嵌套,或者传递了字符串格式的JSON,而Jupyter期望的是笔记本原始JSON结构直接作为content的值(也就是ipynb文件解析后的JSON对象)。
  2. 字段类型不匹配:比如writable应该是布尔值true,而不是字符串"True";mimetype不需要设为"None",要么留空要么设为"application/json",字符串"None"会被服务器识别为无效值。
  3. 请求头缺失或错误:没有设置Content-Type: application/json,导致服务器无法正确解析请求体。

具体Java实现方案

我用OkHttp(Java常用的HTTP客户端)和org.json库来实现,步骤清晰且容易调试:

1. 添加依赖(Maven)

首先在pom.xml里加入需要的依赖:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20240303</version>
</dependency>

2. 完整上传代码

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JupyterNotebookUploader {
    public static void main(String[] args) throws IOException {
        // 配置你的Jupyter Server信息
        String jupyterBaseUrl = "http://localhost:8888"; // 替换成你的服务器地址
        String targetNotebookName = "a.ipynb";
        String localNotebookPath = "/Users/you/path/to/local/a.ipynb"; // 本地文件路径
        String jupyterAuthToken = "your-token-here"; // 如果服务器开启认证,填你的token

        // 第一步:读取本地ipynb文件,直接解析为JSONObject
        String rawNotebookContent = new String(Files.readAllBytes(Paths.get(localNotebookPath)));
        JSONObject notebookJson = new JSONObject(rawNotebookContent);

        // 第二步:构造符合API要求的请求体
        JSONObject requestBody = new JSONObject();
        requestBody.put("name", targetNotebookName);
        requestBody.put("path", ""); // 上传到服务器根目录,可根据需要修改路径
        requestBody.put("type", "notebook");
        requestBody.put("format", "json");
        requestBody.put("content", notebookJson); // 直接放入解析后的笔记本JSON
        requestBody.put("writable", true); // 注意是布尔值,不是字符串

        // 第三步:配置HTTP请求
        OkHttpClient client = new OkHttpClient();
        MediaType jsonMediaType = MediaType.get("application/json; charset=utf-8");
        RequestBody httpRequestBody = RequestBody.create(requestBody.toString(), jsonMediaType);

        // 处理认证:如果有token,拼在URL里或者用Authorization头
        String uploadApiUrl = jupyterBaseUrl + "/api/contents/" + targetNotebookName;
        if (jupyterAuthToken != null && !jupyterAuthToken.isBlank()) {
            uploadApiUrl += "?token=" + jupyterAuthToken;
            // 或者用Authorization头:.addHeader("Authorization", "token " + jupyterAuthToken)
        }

        Request request = new Request.Builder()
                .url(uploadApiUrl)
                .put(httpRequestBody)
                .build();

        // 第四步:发送请求并处理响应
        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println("笔记本上传成功!");
                System.out.println("服务器响应:" + response.body().string());
            } else {
                System.err.println("上传失败,状态码:" + response.code());
                System.err.println("错误详情:" + response.body().string());
            }
        }
    }
}

关键注意事项

  • content字段的正确用法:直接把本地ipynb文件解析后的JSONObject赋值给content,不要做额外的字符串包装,否则服务器会把嵌套的字符串当成无效内容。
  • 字段类型严格匹配:Jupyter API对字段类型要求很严,比如writable必须是布尔值,format必须是"json"(针对notebook类型)。
  • 认证必须正确:如果你的Jupyter Server开启了token认证,一定要在请求中携带token,否则会返回403禁止访问。
  • 调试技巧:如果还是失败,打印最终发送的requestBody.toString(),对比Postman手动请求的正确体,看哪里有差异;同时查看服务器的日志,里面会有详细的错误原因。

内容的提问来源于stack exchange,提问作者Pradip Karad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 23:07:29