当前位置: 代码网 > it编程>编程语言>Java > SpringBoot结合Vue实现Python在线调试器

SpringBoot结合Vue实现Python在线调试器

2026年01月18日 Java 我要评论
项目概述python 在线调试器是一个基于 web 的 python 代码执行和调试工具,支持在线编写、运行和交互式调试 python 代码。项目采用前后端分离架构,前端负责用户界面和交互,后端负责代

项目概述

python 在线调试器是一个基于 web 的 python 代码执行和调试工具,支持在线编写、运行和交互式调试 python 代码。项目采用前后端分离架构,前端负责用户界面和交互,后端负责代码执行和调试逻辑。

技术栈

后端技术栈

技术/框架版本用途
java17编程语言
spring boot3.1.5web框架
spring web-restful api支持
spring validation-参数验证
jackson-json序列化/反序列化
maven3.6+项目构建和依赖管理
python3.x代码执行环境

核心依赖:

  • spring-boot-starter-web: web开发支持
  • spring-boot-starter-websocket: websocket支持(预留扩展)
  • spring-boot-starter-validation: 参数验证
  • jackson-databind: json处理

前端技术栈

技术/框架版本用途
vue.js3.3.4前端框架
vite5.0.0构建工具和开发服务器
codemirror 66.x代码编辑器
axios1.6.0http客户端
node.js16+运行环境
npm-包管理器

核心依赖:

  • @codemirror/lang-python: python语言支持
  • @codemirror/view: 编辑器视图
  • @codemirror/state: 编辑器状态管理
  • @codemirror/theme-one-dark: 深色主题
  • @vitejs/plugin-vue: vite vue插件

架构设计

整体架构

┌─────────────────────────────────────────────────────────┐
│                    浏览器 (browser)                       │
│  ┌──────────────────────────────────────────────────┐   │
│  │          vue 3 前端应用                          │   │
│  │  ┌──────────────┐      ┌──────────────────┐     │   │
│  │  │ codemirror 6 │      │   axios http     │     │   │
│  │  │   编辑器     │      │   客户端         │     │   │
│  │  └──────────────┘      └──────────────────┘     │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────┬───────────────────────────────────────┘
                  │ http/rest api
┌─────────────────┴───────────────────────────────────────┐
│            spring boot 后端 (port: 8080)                 │
│  ┌──────────────────────────────────────────────────┐   │
│  │          pythoncontroller                        │   │
│  │  (rest api 端点)                                 │   │
│  └────────────────┬─────────────────────────────────┘   │
│                   │                                      │
│  ┌────────────────┴─────────────────────────────────┐   │
│  │      pythonexecutionservice                      │   │
│  │  (代码执行和调试逻辑)                             │   │
│  └────────────────┬─────────────────────────────────┘   │
│                   │                                      │
│  ┌────────────────┴─────────────────────────────────┐   │
│  │      processbuilder + python process             │   │
│  │  (执行python代码)                                 │   │
│  └────────────────┬─────────────────────────────────┘   │
│                   │                                      │
│  ┌────────────────┴─────────────────────────────────┐   │
│  │      python 3.x (系统安装)                        │   │
│  │  - pdb (python调试器)                             │   │
│  │  - 代码执行                                       │   │
│  └──────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────┘

分层架构

后端分层

controller层 (pythoncontroller)
    ↓
service层 (pythonexecutionservice)
    ↓
process层 (java processbuilder)
    ↓
python运行时环境

前端分层

视图层 (app.vue template)
    ↓
逻辑层 (app.vue script - composition api)
    ↓
编辑器层 (codemirror 6)
    ↓
http层 (axios)

核心实现方法

1. 代码执行实现

1.1 后端实现 (pythonexecutionservice.executecode)

核心步骤:

创建临时文件

path pythonfile = paths.get(tempdir, "python_" + sessionid + ".py");
files.write(pythonfile, code.getbytes("utf-8"));

启动python进程

processbuilder processbuilder = new processbuilder(pythoncmd, pythonfile.tostring());
processbuilder.environment().put("pythonioencoding", "utf-8");
process process = processbuilder.start();

读取输出

bufferedreader reader = new bufferedreader(
    new inputstreamreader(process.getinputstream(), "utf-8"));
// 设置30秒超时
boolean finished = process.waitfor(30, timeunit.seconds);

清理资源

files.deleteifexists(pythonfile);
runningprocesses.remove(sessionid);

关键技术点:

  • 使用 processbuilder 创建独立的python进程
  • 设置 pythonioencoding=utf-8 确保中文输出正确
  • 使用临时文件存储用户代码
  • 设置执行超时防止死循环
  • utf-8编码处理确保字符正确传输

2. 调试功能实现

2.1 断点插入机制

实现方法:

行号映射表构建

map<integer, integer> linemapping = new hashmap<>();
// 实际行号 -> 原始行号

断点代码注入

// 在断点行之前插入 pdb.set_trace()
result.append(indentstr).append("pdb.set_trace()  # breakpoint at line ")
    .append(originallinenumber).append("\n");

行号映射记录

  • 为所有插入的代码行建立映射
  • 包括 import pdb、空行、pdb.set_trace()
  • 确保能准确还原原始行号

2.2 交互式调试会话管理

debugsession 类:

private static class debugsession {
    process process;              // python进程
    bufferedwriter stdin;         // 标准输入流(发送pdb命令)
    path pythonfile;              // 临时python文件
    boolean isactive;             // 会话是否激活
    int currentline;              // 当前执行行号
    stringbuilder outputbuffer;   // 输出缓冲区
    stringbuilder errorbuffer;    // 错误缓冲区
    map<integer, integer> linemapping; // 行号映射表
}

会话管理:

  • 使用 concurrenthashmap 存储多个调试会话
  • 支持并发调试多个用户
  • 自动清理会话资源

2.3 pdb命令映射

支持的调试操作:

操作pdb命令说明
继续执行c\ncontinue - 继续到下一个断点
单步执行n\nnext - 执行下一行(不进入函数)
步入s\nstep - 进入函数内部
步出u\nup - 返回到调用者

实现方式:

string pdbcommand;
switch (action) {
    case "continue": pdbcommand = "c\n"; break;
    case "step": pdbcommand = "s\n"; break;
    case "stepover": pdbcommand = "n\n"; break;
    case "stepout": pdbcommand = "u\n"; break;
}
session.stdin.write(pdbcommand);
session.stdin.flush();

2.4 行号解析和映射

pdb输出格式解析:

// pdb输出格式: > /path/to/file.py(行号)function_name()
pattern pattern = pattern.compile(">\\s+[^\\(]*\\(\\s*(\\d+)\\s*\\)[^\n]*");

行号转换:

  • 从pdb输出中提取实际行号
  • 通过映射表转换为原始行号
  • 如果没有精确匹配,向上查找最接近的行号
  • 返回给前端显示

3. 前端编辑器实现

3.1 codemirror 6 集成

编辑器初始化:

editorview.value = new editorview({
    doc: codecontent,
    extensions: [
        basicsetup,           // 基础功能
        python(),             // python语言支持
        onedark,              // 深色主题
        breakpointgutter,     // 断点gutter
        currentlinehighlight  // 当前行高亮
    ],
    parent: editorcontainer.value
})

3.2 断点可视化

实现原理:

  • 使用 guttermarker 创建断点标记
  • 使用 statefield 管理断点状态
  • 使用 rangeset 存储断点位置
  • 支持点击gutter区域切换断点

关键代码:

// 断点标记类
class breakpointmarker extends guttermarker {
    todom() {
        const span = document.createelement('span')
        span.classname = 'breakpoint-marker'
        span.textcontent = '●'
        return span
    }
}

// 断点状态字段
const breakpointstate = statefield.define({
    create() { return rangeset.empty },
    update(breakpoints, tr) {
        // 处理断点变更
    }
})

3.3 当前行高亮

实现方法:

// 当前行装饰器
const currentlinedecoration = decoration.line({
    class: 'cm-current-line'
})

// 当前行状态字段
const currentlinestate = statefield.define({
    create() { return rangeset.empty },
    update(currentline, tr) {
        // 更新当前行位置
    },
    provide: f => editorview.decorations.from(f)
})

样式定义:

.cm-current-line {
    background-color: rgba(78, 148, 255, 0.15);
    outline: 1px solid rgba(78, 148, 255, 0.3);
}

关键技术点

1. 进程管理

进程启动:

  • 使用 processbuilder 创建独立进程
  • 分离标准输出和错误输出
  • 设置环境变量确保编码正确

进程控制:

  • 使用 process.waitfor(timeout) 实现超时控制
  • 使用 process.destroyforcibly() 强制终止
  • 使用 concurrenthashmap 管理多个进程

2. 异步i/o处理

输出读取:

thread outputthread = new thread(() -> {
    try (bufferedreader reader = ...) {
        string line;
        while ((line = reader.readline()) != null && session.isactive) {
            synchronized (session.outputbuffer) {
                session.outputbuffer.append(line).append("\n");
            }
        }
    }
});
outputthread.start();

关键点:

  • 使用独立线程读取进程输出
  • 使用同步块保证线程安全
  • 实时解析行号并更新状态

3. 行号映射算法

问题:

  • 插入 import pdbpdb.set_trace() 后行号会偏移
  • pdb显示的是插入后的行号,需要转换为原始行号

解决方案:

  • 构建完整的行号映射表
  • 精确匹配优先
  • 向上查找最接近的行号(最多10行)
  • 如果找不到,使用估算方法

4. 编码处理

utf-8编码设置:

// 后端
processbuilder.environment().put("pythonioencoding", "utf-8");
files.write(pythonfile, code.getbytes("utf-8"));
new inputstreamreader(process.getinputstream(), "utf-8")

// 前端
// axios自动处理utf-8编码

配置文件:

server.servlet.encoding.charset=utf-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
spring.http.encoding.charset=utf-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

5. 会话管理

会话存储:

concurrenthashmap<string, debugsession> debugsessions
concurrenthashmap<string, process> runningprocesses

会话生命周期:

  • 开始调试时创建会话
  • 执行调试命令时更新会话
  • 调试完成或停止时清理会话
  • 自动清理临时文件

api接口设计

1. 代码执行接口

接口: post /api/python/execute

请求体:

{
    "code": "print('hello, world!')",
    "sessionid": "session_123"
}

响应:

{
    "output": "hello, world!\n",
    "error": "",
    "success": true,
    "sessionid": "session_123"
}

2. 调试接口

接口: post /api/python/debug

请求体:

{
    "code": "def func():\n    x = 10\n    return x",
    "sessionid": "session_123",
    "breakpoints": [2, 3],
    "action": "start" | "continue" | "step" | "stepover" | "stepout"
}

响应:

{
    "output": "> file.py(2)func()\n-> x = 10",
    "error": "",
    "success": true,
    "currentline": 2,
    "sessionid": "session_123"
}

3. 停止执行接口

接口: post /api/python/stop/{sessionid}

响应:

执行已停止

调试功能实现原理

1. 断点插入流程

原始代码                   插入后代码
─────────────────         ─────────────────
1 def func():            1 import pdb
2     x = 10             2 
3     return x           3 def func():
                         4     pdb.set_trace()  # breakpoint at line 2
                         5     x = 10
                         6     return x

行号映射:
实际行号 -> 原始行号
4 -> 2
5 -> 2

2. pdb交互流程

前端                后端                 python进程
│                   │                      │
│-- startdebug ---->│                      │
│                   │-- 创建临时文件 ----->│
│                   │-- 启动进程 --------->│
│                   │<-- pdb暂停在第n行 ---│
│<-- 返回行号n -----│                      │
│                   │                      │
│-- step ---------->│                      │
│                   │-- 发送 's\n' ------->│
│                   │                      │-- 步入函数
│                   │<-- pdb暂停在第m行 ---│
│<-- 返回行号m -----│                      │

3. 行号解析流程

pdb输出: "> file.py(15)func()\n-> x = 10"
         ↓
正则匹配: pattern.compile(">\s+[^\(]*\(\s*(\d+)\s*\)")
         ↓
提取行号: 15
         ↓
查找映射: linemapping.get(15) = 12
         ↓
返回前端: currentline = 12

前端交互实现

1. vue 3 composition api

响应式状态:

const breakpoints = ref([])
const currentdebugline = ref(null)
const isindebugmode = ref(false)

生命周期管理:

onmounted(() => {
    initeditor()
    sessionid.value = generatesessionid()
    window.addeventlistener('keydown', handlekeypress)
})

onunmounted(() => {
    window.removeeventlistener('keydown', handlekeypress)
})

2. 断点管理

添加断点:

const addbreakpoint = () => {
    if (newbreakpoint.value && newbreakpoint.value > 0) {
        if (!breakpoints.value.includes(linenum)) {
            breakpoints.value.push(linenum)
            breakpoints.value.sort((a, b) => a - b)
            syncbreakpointstoeditor()
        }
    }
}

断点同步:

watch(breakpoints, () => {
    nexttick(() => {
        syncbreakpointstoeditor()
    })
}, { deep: true })

3. 调试控制

调试命令执行:

const executedebugcommand = async (action) => {
    const response = await axios.post(`${api_base}/debug`, {
        code: '',
        sessionid: sessionid.value,
        breakpoints: [],
        action: action  // 'continue', 'step', 'stepover', 'stepout'
    })
    
    // 更新当前行号并高亮
    if (result.currentline) {
        currentdebugline.value = result.currentline
        highlightcurrentline(result.currentline)
    }
}

键盘快捷键:

  • f5: 继续执行
  • f7: 步入
  • f8: 单步执行
  • shift+f8: 步出

4. 实时更新机制

当前行高亮更新:

const highlightcurrentline = (linenum) => {
    const view = editorview.value
    const line = view.state.doc.line(linenum)
    view.dispatch({
        effects: [
            editorview.scrollintoview(line.from, { y: 'center' }),
            setcurrentlineeffect.of(line.from)
        ]
    })
}

部署方案

附代码仓库链接:https://gitee.com/ghostmen/python-debug-demo

开发环境

后端:

  • 端口:8080
  • 启动:![img](http://localhost:63342/markdownpreview/1811665444/commandrunner/run.png)mvn spring-boot:run
  • 或使用:start-backend.bat / start-backend.sh

前端:

  • 端口:3000
  • 启动:npm run dev
  • 或使用:start-frontend.bat / start-frontend.sh
  • vite代理:/apihttp://localhost:8080

生产环境建议

后端:

  • 打包:![img](http://localhost:63342/markdownpreview/1811665444/commandrunner/run.png)mvn clean package
  • 运行:java -jar target/python-debug-backend-1.0.0.jar
  • 配置:修改 application.properties
  • 反向代理:nginx

前端:

  • 构建:npm run build
  • 输出目录:dist/
  • 静态资源服务器:nginx / apache
  • 或集成到后端静态资源

安全建议

代码执行限制

  • 添加沙箱机制
  • 限制系统调用
  • 限制资源使用(cpu、内存)

网络安全

  • 配置具体的cors允许域名
  • 使用https
  • 添加身份验证

输入验证

  • 验证代码长度
  • 过滤危险操作
  • 设置执行超时

性能优化

1. 进程管理优化

  • 限制并发执行的进程数
  • 及时清理已完成的进程
  • 使用线程池管理i/o操作

2. 前端优化

  • 代码编辑器懒加载
  • 输出内容虚拟滚动(大量输出时)
  • 防抖处理频繁的断点操作

3. 缓存策略

  • 缓存python命令检测结果
  • 复用调试会话(如果可能)

扩展方案

1. websocket实时交互

优势:

  • 实时双向通信
  • 更好的调试体验
  • 支持断点处的变量查看

实现方向:

  • 使用 spring websocket
  • 前端使用 websocket api
  • 实时推送调试状态

2. 使用debugpy替代pdb

优势:

  • 更专业的调试协议(dap)
  • 更好的性能
  • 支持更多调试功能

实现方向:

  • 集成debugpy库
  • 实现dap协议客户端
  • 支持变量查看、表达式求值等

3. 多文件支持

实现方向:

  • 文件管理器组件
  • 多标签编辑器
  • 文件间依赖管理

4. 代码补全

实现方向:

  • 集成python语言服务器(如pyright)
  • codemirror自动补全扩展
  • 提供代码提示和错误检查

技术难点与解决方案

难点1: 行号映射准确性

问题: 插入调试代码后,行号偏移,需要准确映射回原始行号。

解决方案:

  • 建立完整的行号映射表
  • 使用向上查找算法作为备选
  • 智能匹配最接近的行号

难点2: pdb输出解析

问题: pdb输出格式多样,需要准确提取当前行号。

解决方案:

  • 使用正则表达式匹配多种格式
  • 从后往前查找最新的pdb提示符
  • 容错处理,支持多种输出格式

难点3: 异步i/o同步

问题: 异步读取输出与同步操作之间的时序问题。

解决方案:

  • 使用同步块保护共享资源
  • 合理的等待时间
  • 状态标志控制异步读取

难点4: 编码问题

问题: windows系统默认gbk编码,导致中文乱码。

解决方案:

  • 设置 pythonioencoding=utf-8 环境变量
  • 统一使用utf-8编码
  • spring boot配置utf-8响应编码

总结

本项目采用前后端分离架构,使用spring boot 3.x和vue 3构建,通过processbuilder执行python代码,使用pdb实现交互式调试。核心特点:

  • 技术选型合理:现代化的技术栈,易于维护和扩展
  • 实现方案可行:使用成熟的processbuilder和pdb,稳定性好
  • 用户体验良好:可视化断点、当前行高亮、快捷键支持
  • 扩展性强:预留websocket接口,可升级到更专业的调试方案

改进方向:

  • 使用debugpy实现更专业的调试
  • 添加websocket实现实时交互
  • 增强安全性和性能优化
  • 支持更多调试功能(变量查看、表达式求值等)

以上就是springboot结合vue实现python在线调试器的详细内容,更多关于springboot在线调试python的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com