当前位置: 首页 > news >正文

#2026山东大学软件学院项目实训(四)——AI应用生成模块完整实现

文章标签:#Java #SpringBoot #SSE #AI编程 #LangChain4j

一、模块整体设计思路

AI应用生成模块是AI零代码应用生成平台的核心功能,负责将单机版AI代码生成能力与应用管理系统深度集成,实现用户-应用-代码的绑定关联。

本模块遵循核心设计原则:

  1. 应用绑定:代码生成与应用ID强关联,文件按应用ID规范存储
  2. 流式响应:采用SSE服务器推送技术,实现代码实时流式输出
  3. 权限校验:仅应用创建者可触发代码生成,保障数据安全
  4. 文件规范:统一文件目录命名规则,避免存储混乱
  5. 异常统一:全局捕获异常,返回友好错误提示

二、AI应用生成服务开发

1. 业务流程设计

平台化代码生成核心流程:

  1. 用户在主页输入提示词创建应用,生成应用记录入库
  2. 获取应用ID后跳转至AI对话页面
  3. 前端调用SSE流式生成接口,后端校验权限并触发AI生成
  4. 代码按codeGenType_appId规则保存至文件系统
  5. 流式返回生成内容至前端,实时展示生成效果

2. 核心代码改造

(1)代码保存模板改造(CodeFileSaverTemplate)

重构代码保存逻辑,新增应用ID参数,实现文件与应用绑定:

/** * 模板方法:保存代码的标准流程(使用appId) * @param result 代码结果对象 * @param appId 应用ID * @return 保存的目录 */publicfinalFilesaveCode(Tresult,LongappId){// 1.验证输入validateInput(result);// 2.构建基于appId的目录StringbaseDirPath=buildUniqueDir(appId);// 3.保存文件(具体实现由子类提供)saveFiles(result,baseDirPath);// 4.返回目录文件对象returnnewFile(baseDirPath);}/** * 构建基于appId的目录路径 * @param appId 应用ID * @return 目录路径 */protectedfinalStringbuildUniqueDir(LongappId){if(appId==null){thrownewBusinessException(ErrorCode.PARAMS_ERROR,"应用ID不能为空");}StringcodeType=getCodeType().getValue();StringuniqueDirName=StrUtil.format("{}_{}",codeType,appId);StringdirPath=FILE_SAVE_ROOT_DIR+File.separator+uniqueDirName;FileUtil.mkdir(dirPath);returndirPath;}
(2)代码保存执行器改造(CodeFileSaverExecutor)

修改执行方法,补充appId参数,适配新的保存逻辑:

/** * 执行代码保存(使用appId) * @param codeResult 代码结果对象 * @param codeGenType 代码生成类型 * @param appId 应用ID * @return 保存的目录 */publicstaticFileexecuteSaver(ObjectcodeResult,CodeGenTypeEnumcodeGenType,LongappId){returnswitch(codeGenType){caseHTML->htmlCodeFileSaver.saveCode((HtmlCodeResult)codeResult,appId);caseMULTI_FILE->multiFileCodeFileSaver.saveCode((MultiFileCodeResult)codeResult,appId);default->thrownewBusinessException(ErrorCode.SYSTEM_ERROR,"不支持的代码生成类型:"+codeGenType);};}
(3)AI代码生成门面改造(AiCodeGeneratorFacade)

所有生成方法新增appId参数,同步适配流式生成:

/** * 统一入口:根据类型生成并保存代码(流式, 使用appId) * @param userMessage 用户提示词 * @param codeGenTypeEnum 生成类型 * @param appId 应用ID * @return 流式响应 */publicFlux<String>generateAndSaveCodeStream(StringuserMessage,CodeGenTypeEnumcodeGenTypeEnum,LongappId){if(codeGenTypeEnum==null){thrownewBusinessException(ErrorCode.SYSTEM_ERROR,"生成类型为空");}returnswitch(codeGenTypeEnum){caseHTML->{Flux<String>codeStream=aiCodeGeneratorService.generateHtmlCodeStream(userMessage);yieldprocessCodeStream(codeStream,CodeGenTypeEnum.HTML,appId);}caseMULTI_FILE->{Flux<String>codeStream=aiCodeGeneratorService.generateMultiFileCodeStream(userMessage);yieldprocessCodeStream(codeStream,CodeGenTypeEnum.MULTI_FILE,appId);}default->{StringerrorMessage="不支持的生成类型:"+codeGenTypeEnum.getValue();thrownewBusinessException(ErrorCode.SYSTEM_ERROR,errorMessage);}};}
(4)应用服务生成方法(AppService#chatToGenCode)

实现权限校验、应用查询、AI生成调用的核心逻辑:

@OverridepublicFlux<String>chatToGenCode(LongappId,Stringmessage,UserloginUser){// 1.参数校验ThrowUtils.throwIf(appId==null||appId<=0,ErrorCode.PARAMS_ERROR,"应用ID不能为空");ThrowUtils.throwIf(StrUtil.isBlank(message),ErrorCode.PARAMS_ERROR,"用户消息不能为空");// 2.查询应用信息Appapp=this.getById(appId);ThrowUtils.throwIf(app==null,ErrorCode.NOT_FOUND_ERROR,"应用不存在");// 3.验证权限:仅本人可生成代码if(!app.getUserId().equals(loginUser.getId())){thrownewBusinessException(ErrorCode.NO_AUTH_ERROR,"无权限访问该应用");}// 4.获取代码生成类型StringcodeGenTypeStr=app.getCodeGenType();CodeGenTypeEnumcodeGenTypeEnum=CodeGenTypeEnum.getEnumByValue(codeGenTypeStr);if(codeGenTypeEnum==null){thrownewBusinessException(ErrorCode.SYSTEM_ERROR,"不支持的代码生成类型");}// 5.调用AI生成代码returnaiCodeGeneratorFacade.generateAndSaveCodeStream(message,codeGenTypeEnum,appId);}

三、SSE流式接口开发

1. 接口设计

采用SSE(Server-Sent Events)实现流式响应,使用GET请求便于前端EventSource对接,声明响应类型为text/event-stream

2. 核心接口代码(AppController)

/** * 应用聊天生成代码(流式SSE) * @param appId 应用ID * @param message 用户消息 * @param request 请求对象 * @return 生成结果流 */@GetMapping(value="/chat/gen/code",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<String>chatToGenCode(@RequestParamLongappId,@RequestParamStringmessage,HttpServletRequestrequest){// 参数校验ThrowUtils.throwIf(appId==null||appId<=0,ErrorCode.PARAMS_ERROR,"应用ID无效");ThrowUtils.throwIf(StrUtil.isBlank(message),ErrorCode.PARAMS_ERROR,"用户消息不能为空");// 获取当前登录用户UserloginUser=userService.getLoginUser(request);// 调用服务生成代码(流式)returnappService.chatToGenCode(appId,message,loginUser);}

四、SSE流式接口优化

原生SSE接口存在空格丢失无法区分正常结束/异常中断两大问题,需针对性优化。

1. 优化1:解决前端空格丢失问题

问题原因

前端EventSource解析纯文本流式数据时,空格/换行符会被异常过滤,导致代码格式错乱。

解决方案

将流式数据封装为ServerSentEvent,数据转为JSON格式传输,保留原始格式。

2. 优化2:添加生成完成标识

问题原因

SSE默认通过关闭连接标识传输结束,无法区分正常完成网络异常中断

解决方案

追加done事件,前端通过监听事件类型判断生成状态。

3. 优化后完整接口代码

/** * 应用聊天生成代码(优化版SSE) * @param appId 应用ID * @param message 用户消息 * @param request 请求对象 * @return 优化后流式响应 */@GetMapping(value="/chat/gen/code",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<ServerSentEvent<String>>chatToGenCode(@RequestParamLongappId,@RequestParamStringmessage,HttpServletRequestrequest){// 参数校验ThrowUtils.throwIf(appId==null||appId<=0,ErrorCode.PARAMS_ERROR,"应用ID无效");ThrowUtils.throwIf(StrUtil.isBlank(message),ErrorCode.PARAMS_ERROR,"用户消息不能为空");// 获取当前登录用户UserloginUser=userService.getLoginUser(request);// 调用服务生成代码Flux<String>contentFlux=appService.chatToGenCode(appId,message,loginUser);// 封装数据+添加结束事件returncontentFlux.map(chunk->{// 封装为JSON,保留空格格式Map<String,String>wrapper=Map.of("d",chunk);StringjsonData=JSONUtil.toJsonStr(wrapper);returnServerSentEvent.<String>builder().data(jsonData).build();}).concatWith(Mono.just(// 发送done事件标识生成完成ServerSentEvent.<String>builder().event("done").data("").build()));}

五、接口测试

1. 测试步骤

  1. 用户登录获取会话
  2. 调用SSE流式生成接口
  3. 查看实时输出结果

2. 测试命令(CURL)

# 1.用户登录,保存cookiecurl-XPOST"http://localhost:8123/api/user/login"\-H"Content-Type: application/json"\-d'{"userAccount":"yupi","userPassword":"12345678"}'\-ccookies.txt# 2.调用SSE流式生成接口curl-G"http://localhost:8123/api/app/chat/gen/code"\--data-urlencode"appId=303320512563961856"\--data-urlencode"message=我需要一个简单的任务记录工具网站"\-H"Accept: text/event-stream"\-H"Cache-Control: no-cache"\-bcookies.txt\--no-buffer

3. 测试效果

优化后接口可正常保留空格/换行,生成完成后触发done事件,前端可精准判断生成状态。

六、模块核心要点总结

  1. 应用绑定:通过appId关联代码文件,解决平台化存储混乱问题
  2. 流式响应:SSE技术实现代码实时输出,提升用户交互体验
  3. 双层优化:JSON封装解决空格丢失,done事件明确生成结束状态
  4. 权限管控:仅应用创建者可触发生成,保障平台数据安全
  5. 规范统一:文件目录、接口返回、异常处理全链路标准化
http://www.jsqmd.com/news/706141/

相关文章:

  • AI Agent Harness Engineering 盈利模式设计:订阅制、按次付费与定制化服务
  • 零基础极速上手:普通人如何用AI建站工具10分钟搭建个人网站
  • Copilot Next 工作流配置全解析,深度拆解TypeScript项目自动测试生成+PR注释+文档同步链路
  • MCP 2026集成合规红线预警:5类非标组件已列入2026Q2禁用目录,你还在用吗?
  • 2026年想选好用的郑州联想电脑代理?哪家公司靠谱值得一探究竟! - 速递信息
  • 惯性摩擦焊机早期故障检测与排除技术实现【附代码】
  • 2026年祠堂升级!揭秘祠堂石雕定制,这些雕刻内容你知道吗?
  • 2026Q2优质家用预适应训练仪排行:便携预适应训练仪/全自动缺血预适应训练仪/家用超声波治疗仪/缺氧预适应训练仪/选择指南 - 优质品牌商家
  • 汕头海门木松鱼丸总店在哪?唯一正宗地址、电话与购买指南 - 速递信息
  • 2026年家谱软件技术解析:家谱软件那个好、族谱制作软件哪个好、族谱软件哪个好用、望族家史数字化家谱平台、比较好的家谱软件选择指南 - 优质品牌商家
  • 【Backend Flow工程实践 08】LEF / Liberty / Verilog / DEF:Backend Flow 为什么依赖多格式协同?
  • 知识图谱本体论体系:理论基础、构建方法与应用展望
  • 【Backend Flow工程实践 09】Design Import 不是读文件:它是在建立设计数据库的第一层语义
  • 2026氨分解纯化技术解析:制氮机氮气纯化、制氮机维修、制氮机设备改造、变压吸附制氮机、工业制氮机、氨分解发生炉选择指南 - 优质品牌商家
  • 算法训练营第十四天|18.四数之和
  • DocsGPT 二次开发:打造面向国内用户的私有 AI 知识库平台
  • 高精度 98陀螺 0.01度/小时 2.7w
  • Cubase15.0.21 Pro一键安装完整版下载安装Cubase 15 Pro最新版下载安装教程支持Win/Mac双系统版送104G原厂音源Mac系统苹果不关SIP安装Cubase15.0.21
  • 权威见证:Ledger 携手京东开启官方授权新篇章,正品保障触手可及
  • 太阳能路灯选技术,看准这三点不踩坑
  • DevEco Studio:卡片预览
  • 海凌科HLK-W801开发板开箱:从零配置平头哥CDK到MQTT通信实战
  • 若依Vue3.8.2项目开发+Gitee提交完整流程(学生信息模块)
  • 躲进弹坑更安全吗?
  • 2026年呼和浩特正规床垫厂家销售TOP5,你知道几个?
  • 2026云南纯水设备标杆名录:云南净水设备、云南污水处理、云南纯水设备、四川净水设备、四川污水处理、四川纯水设备选择指南 - 优质品牌商家
  • Materialize:用SQL实现毫秒级实时数据处理的增量物化视图引擎
  • 《深耕QClaw协作逻辑,构建无误解的智能体沟通体系》
  • 边缘计算中视觉语言动作模型的优化与加速
  • STM32CubeMX生成的工程,为什么开发板能跑QEMU却不行?深入排查SystemInit函数