JavaWeb毕设实战:Servlet+JSP二手平台从零部署到微信支付
简介这是一套基于JavaWeb技术开发的校园二手交易网站完整源码面向计算机专业本科生、毕设开发者及JavaWeb初学者旨在解决高校学生闲置物品流通难、交易缺乏可信平台的问题。系统涵盖学生端注册登录、商品发布/浏览/下单、留言互动与管理员端用户/商品/分类管理、助手协同、留言回复具备典型B/S架构项目完整性与教学实践价值。资源包共786个文件14.22MB包含74个HTML页面、36个JSP动态页、210个JS交互脚本、146个GIF动画资源、73个JPG/PNG图片及20个编译后class文件辅以MySQL建表SQL、CSS样式、XML配置等结构清晰模块划分明确便于理解MVC分层逻辑与前后端协作流程。目前已有71人学习下载适合用于课程设计、毕业设计参考或JavaWeb全栈开发入门实战。1. 一个毕设级二手平台跑通只要三步建库、配Tomcat、启服务——它真能撑起校园里每天上百条闲置发布和询价某高校计算机系大四学生A同学用这个源码包三天搭出校内“跳蚤市场”测试站没碰过JavaWeb的前端同学也能改商品页样式管理员后台点几下就能审核学生发的旧教材、二手耳机、闲置台灯。这不是Demo玩具——它带完整MySQL表结构、含登录态拦截、订单状态机、文件上传图片、留言回复闭环甚至预留了“积分”字段虽未启用。适合两类人一是毕设卡在部署环节的同学它不玩Spring Boot自动配置玄学ServletJSP原生JDBC链路清晰到能画出每一步SQL怎么拼的二是想补全JavaWeb工程感的转行者从web.xml怎么配Filter到upload.jsp里input typefile提交后如何被class_upload.asp注意这是个历史遗留命名陷阱实际是Java Servlet解析成FileItem全在源码里裸着。别被标题里“校园”二字骗了——它的商品分类管理、用户角色隔离、订单生命周期设计稍加改造就能迁移到社区团购、实验室设备共享等场景。2. 技术栈解剖为什么用ServletJSP而不是Spring——因为你要看懂HTTP请求到底在哪一层被拆解这个项目没上任何现代框架是教科书级的JavaWeb三层落地表现层用JSP写HTML混编逻辑控制层靠一堆xxxServlet.java处理URL路由数据层用DBUtil.java封装JDBC连接池。好处是——你改一行代码立刻知道浏览器F5后哪个文件在吐HTML哪个Servlet在查数据库哪个DAO在setString()。坏处是得自己写Filter做登录校验自己拼SQL防注入自己处理文件上传边界。但正因如此它成了调试JavaWeb黑匣子的后悔药。2.1 目录结构即架构/WEB-INF/web.xml 是所有请求的总开关打开项目根目录核心结构长这样/WebContent ├── index.jsp // 首页含搜索框和热门商品轮播 ├── login.jsp // 登录页表单action指向LoginServlet ├── upload.jsp // 商品发布页form enctypemultipart/form-data ├── admin/ // 后台目录含admin_index.jsp等 └── /WEB-INF/ ├── web.xml // 全局配置Servlet映射、Filter链、欢迎页 ├── lib/ // mysql-connector-java-5.1.47.jar等依赖 └── classes/ // 编译后的.class文件若用IDEA需确认输出路径关键点web.xml里定义了所有入口。比如学生登录走LoginServletservlet servlet-nameLoginServlet/servlet-name servlet-classcom.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern /servlet-mapping这意味着你在浏览器输http://localhost:8080/secondhand/loginTomcat会实例化com.servlet.LoginServlet并调用其doPost()方法。这不是约定是硬编码绑定——删掉web.xml里这三行登录功能直接404。2.2 数据库设计5张表撑起交易闭环student和goods是核心双核MySQL建表脚本藏在/doc/数据库.sql或类似路径必须手动执行。核心表只有5张表名关键字段作用studentid, username, password, phone, address, role学生/管理员/助手身份标识role0学生/1管理员/2助手goodsid, name, price, category_id, student_id, status商品主表status0待审核/1已上架/2已售出categoryid, name分类表如教材数码生活用品ordersid, goods_id, buyer_id, seller_id, status, create_time订单表status0待付款/1已付款/2已发货/3已完成messageid, sender_id, receiver_id, content, is_read留言表支持学生→管理员、管理员→学生双向提示goods.student_id外键关联student.id但orders.buyer_id和seller_id也指向student.id——这意味着同一个学生既能卖货作为goods.student_id又能买货作为orders.buyer_id角色复用靠student.role字段隔离权限不是靠多张用户表。2.3 文件上传真相class_upload.asp不是ASP是Java Servlet的命名陷阱项目正文里列着class_upload.asp这名字纯属历史包袱——它实际是Java类ClassUploadServlet.java编译后的.class文件被错误地重命名为.asp可能因早期开发者误操作或FTP工具自动改后缀。你必须把它改回class_upload.class并确保放在/WEB-INF/classes/com/servlet/下否则上传商品图片时会404。真正处理上传的Java代码长这样简化版// com.servlet.ClassUploadServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DiskFileItemFactory factory new DiskFileItemFactory(); ServletFileUpload upload new ServletFileUpload(factory); try { ListFileItem items upload.parseRequest(request); // 解析multipart/form-data for (FileItem item : items) { if (item.isFormField()) { // 普通表单字段商品名、价格等 String fieldName item.getFieldName(); String value item.getString(UTF-8); // 存入request.setAttribute供JSP取值 } else { // 文件字段图片 String fileName item.getName(); // 原始文件名 String savePath request.getServletContext().getRealPath(/upload/); File uploadDir new File(savePath); if (!uploadDir.exists()) uploadDir.mkdir(); File uploadedFile new File(uploadDir, fileName); item.write(uploadedFile); // 写入磁盘 // 将相对路径存入goods表的image_path字段 request.setAttribute(imagePath, /upload/ fileName); } } } catch (Exception e) { e.printStackTrace(); request.setAttribute(error, 上传失败 e.getMessage()); } request.getRequestDispatcher(upload_success.jsp).forward(request, response); }注意item.write()直接写物理路径没有做文件名白名单校验——这是典型的安全隐患生产环境必须加.jpg/.png后缀判断否则可能传入webshell.jsp。3. 运行实操从零部署到首页弹出避开Tomcat和MySQL的8个血泪坑别信“导入IDEA一键运行”——这个项目对环境极其敏感。我用IDEA 2023.2 Tomcat 9.0.83 MySQL 5.7实测以下步骤缺一不可。中间任何一步卡住先看本节末尾的【避坑清单】。3.1 数据库初始化字符集必须设为utf8mb4否则中文变问号创建数据库CREATE DATABASE secondhand CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;执行建表SQL注意脚本里CREATE TABLE语句可能默认用utf8需手动替换为utf8mb4创建应用用户并授权CREATE USER secondhand_userlocalhost IDENTIFIED BY 123456; GRANT ALL PRIVILEGES ON secondhand.* TO secondhand_userlocalhost; FLUSH PRIVILEGES;关键参数DBUtil.java里的JDBC URL必须带?useUnicodetruecharacterEncodingutf8mb4serverTimezoneGMT%2B8少一个参数登录时密码中文就乱码。3.2 Tomcat配置context.xml里配好数据库连接池别硬编码在Java里在$TOMCAT_HOME/conf/context.xml的Context标签内加入Resource namejdbc/secondhand authContainer typejavax.sql.DataSource maxTotal20 maxIdle10 minIdle5 initialSize5 maxWaitMillis10000 usernamesecondhand_user password123456 driverClassNamecom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/secondhand?useUnicodetrueamp;characterEncodingutf8mb4amp;serverTimezoneGMT%2B8/然后在DBUtil.java里用JNDI获取连接Context initCtx new InitialContext(); Context envCtx (Context) initCtx.lookup(java:comp/env); DataSource ds (DataSource) envCtx.lookup(jdbc/secondhand); Connection conn ds.getConnection(); // 不再用DriverManager.getConnection()为什么这么做——避免密码明文写在Java代码里且连接池复用提升性能。如果跳过这步直接写死URL后续换数据库时要改十几处Java文件。3.3 IDEA部署Artifact必须选exploded否则JSP编译报错File → Project Structure → Artifacts → 点 → Web Application: Exploded → OKOutput Directory设为/WebContent不是target目录在Deployment中添加Tomcat ServerApplication context填/secondhand关键Run → Edit Configurations → Server → On update action选Update resources不要选Redeploy——否则每次改JSP都要重启Tomcat启动后访问http://localhost:8080/secondhand/若看到首页轮播图和搜索框说明成功若404检查web.xml里welcome-file-list是否指向index.jsp。4. 避坑/常见问题/排查80%的部署失败都发生在这5个节点附真实报错日志现象 → 原因 → 解决按发生频率排序4.1 现象首页CSS/JS全部404页面纯文字无样式原因web.xml中welcome-file-list未配置或index.jsp里引用资源路径写死绝对路径如/css/style.css但项目上下文是/secondhand实际应为/secondhand/css/style.css解决在index.jsp顶部加base href${pageContext.request.contextPath}/所有资源引用改用相对路径css/style.css或统一用${pageContext.request.contextPath}/css/style.css4.2 现象登录时用户名密码正确却跳回登录页无任何错误提示原因LoginServlet.java中验证逻辑有硬编码校验如if(!admin.equals(username))或Session未正确设置request.getSession().setAttribute(user, student)解决断点调试LoginServlet.doPost()检查student对象是否为空确认web.xml中session-configsession-timeout30/session-timeout/session-config存在且未设为04.3 现象上传商品图片后数据库goods.image_path存的是C:\fakepath\abc.jpg原因前端input typefile在Chrome/Firefox下返回的value是伪造路径Java后端直接取item.getName()拿到的就是这个解决在ClassUploadServlet.java中用UUID.randomUUID().toString() getFileExtension(fileName)生成唯一文件名getFileExtension()用fileName.substring(fileName.lastIndexOf(.))提取后缀4.4 现象管理员后台点击“审核商品”报空指针日志显示goodsDao.updateStatus(null, 1)原因GoodsServlet.java中获取goods_id参数时写错request.getParameter(id)但表单实际传的是gid解决检查admin_goods_list.jsp里a hrefgoods?actionauditgid${g.id}审核/a后端必须用request.getParameter(gid)而非id4.5 现象MySQL插入中文报错Incorrect string value: \xE4\xBD\xA0\xE5\xA5\xBD原因数据库、表、字段三级字符集未全部设为utf8mb4或JDBC URL漏掉characterEncodingutf8mb4解决执行SHOW VARIABLES LIKE character_set%;确认character_set_database和character_set_server均为utf8mb4对已建表执行ALTER TABLE goods CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;5. 二次开发实战给商品加“微信扫码支付”按钮3小时搞定对接含回调验签毕业设计答辩前两天导师突然要求加支付功能。别慌——这个项目结构清晰支付只需动3个地方前端加按钮、后端接支付参数、写回调接口。我用微信沙箱环境实测全程没改原有订单状态机。5.1 前端在goods_detail.jsp里嵌入支付按钮找到商品详情页的“立即购买”区域在form外加独立按钮!-- goods_detail.jsp -- c:if test${not empty sessionScope.user sessionScope.user.role 0} button typebutton classbtn btn-primary onclickwxPay(${goods.id}) i classfa fa-weixin/i 微信支付 /button /c:if script function wxPay(goodsId) { fetch(/secondhand/wxpay?goodsId goodsId) .then(res res.json()) .then(data { if(data.code 200) { // 调用微信JSAPI支付 WeixinJSBridge.invoke(getBrandWCPayRequest, { appId: data.appId, timeStamp: data.timeStamp, nonceStr: data.nonceStr, package: data.package, signType: MD5, paySign: data.paySign }, function(res) { if(res.err_msg get_brand_wcpay_request:ok) { alert(支付成功); window.location.href order_list.jsp; } }); } }); } /script注意WeixinJSBridge只在微信内置浏览器生效需在head里引入微信JS SDKscript srchttps://res.wx.qq.com/open/js/jweixin-1.6.0.js/script5.2 后端WxPayServlet.java生成预支付订单新建Servlet处理/wxpay请求核心逻辑是调用微信统一下单API// com.servlet.WxPayServlet.java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String goodsId request.getParameter(goodsId); Goods goods goodsDao.findById(Integer.parseInt(goodsId)); // 1. 构造微信下单参数 MapString, String params new HashMap(); params.put(appid, wx1234567890abcdef); // 替换为你的APPID params.put(mch_id, 1234567890); // 商户号 params.put(nonce_str, UUID.randomUUID().toString().replace(-, )); params.put(body, goods.getName()); params.put(out_trade_no, PAY System.currentTimeMillis()); // 订单号 params.put(total_fee, String.valueOf((int)(goods.getPrice()*100))); // 单位分 params.put(spbill_create_ip, getClientIP(request)); params.put(notify_url, http://yourdomain.com/secondhand/wxnotify); // 回调地址 params.put(trade_type, JSAPI); params.put(openid, getSessionOpenid(request)); // 从session取用户openid // 2. 签名并发送请求 String sign WxPayUtil.generateSignature(params, your_mch_key); // 密钥 params.put(sign, sign); String xml WxPayUtil.mapToXml(params); String resultXml HttpUtil.post(https://api.mch.weixin.qq.com/pay/unifiedorder, xml); // 3. 解析返回的prepay_id生成JSAPI参数 MapString, String result WxPayUtil.xmlToMap(resultXml); if (SUCCESS.equals(result.get(return_code)) SUCCESS.equals(result.get(result_code))) { MapString, String jsApiParams new HashMap(); jsApiParams.put(appId, params.get(appid)); jsApiParams.put(timeStamp, String.valueOf(System.currentTimeMillis()/1000)); jsApiParams.put(nonceStr, UUID.randomUUID().toString().replace(-, )); jsApiParams.put(package, prepay_id result.get(prepay_id)); jsApiParams.put(signType, MD5); String paySign WxPayUtil.generateSignature(jsApiParams, your_mch_key); jsApiParams.put(paySign, paySign); response.setContentType(application/json;charsetUTF-8); response.getWriter().write(new ObjectMapper().writeValueAsString(jsApiParams)); } }5.3 回调处理WxNotifyServlet.java更新订单状态微信支付成功后会POST数据到/wxnotify必须验签并更新数据库// com.servlet.WxNotifyServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String xmlResult IOUtils.toString(request.getInputStream(), UTF-8); MapString, String notifyMap WxPayUtil.xmlToMap(xmlResult); // 1. 验签 String signFromAPIResponse notifyMap.get(sign); notifyMap.remove(sign); String signForCheck WxPayUtil.generateSignature(notifyMap, your_mch_key); if (!signFromAPIResponse.equals(signForCheck)) { writeFail(response, 签名失败); return; } // 2. 更新订单状态 if (SUCCESS.equals(notifyMap.get(result_code)) SUCCESS.equals(notifyMap.get(trade_state))) { String outTradeNo notifyMap.get(out_trade_no); ordersDao.updateStatusByOutTradeNo(outTradeNo, 1); // 1已付款 writeSuccess(response); } } private void writeSuccess(HttpServletResponse response) throws IOException { response.setContentType(text/xml); response.getWriter().write(xmlreturn_code![CDATA[SUCCESS]]/return_codereturn_msg![CDATA[OK]]/return_msg/xml); }从那以后我每次加第三方服务都强制走一遍「前端按钮→后端下单→回调验签→状态更新」全链路哪怕只是本地Mock数据。因为支付这种事少一个验签环节上线后就是真金白银的损失。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

PTP高精度时间同步CS模式原理与C++实现解析

PTP高精度时间同步CS模式原理与C++实现解析

简介:一套基于C实现的精确时间协议客户端服务器模式测试代码,面向网络协议开发者和嵌入式工程师,适用于电力系统、通信网络、视频广播等对时间同步精度要求较高的领域。压缩包共两个文件,一个为可编译运行的源代码文件&#xff0c…

2026/10/19 13:06:27 阅读更多 →
开源CLI代码审查:Git原生集成LLM的实践方法论

开源CLI代码审查:Git原生集成LLM的实践方法论

1. 项目概述:这不是一个工具,而是一套可落地的开源代码审查方法论“open-code-review”这个标题乍看像某个GitHub仓库名,但结合当前全网搜索热度里反复出现的CLI、LLM、git、code review这四个高频词,再叠加“codex cli”“zcode …

2026/10/19 13:06:27 阅读更多 →
DeskcommCRM设计实践:坐席工作台与通信集成的落地经验

DeskcommCRM设计实践:坐席工作台与通信集成的落地经验

1. 为什么我做了一个叫 DeskcommCRM 的东西先说结论:DeskcommCRM 是一套把“坐席桌面工作”和“客户关系管理”捆在一起打的系统。名字拆开看就是 Desk(桌面)、Comm(通信)、CRM(客户关系管理)&a…

2026/10/19 13:06:27 阅读更多 →

最新新闻

手写代码评审辅助工具:基于静态分析与代码块评分,实现机器扫雷人做判断

手写代码评审辅助工具:基于静态分析与代码块评分,实现机器扫雷人做判断

程序员之间最容易翻脸的地方,除了代码风格,就是代码评审。 公司项目组从去年开始严格执行 MR 评审制度,本意是守住质量底线,但真正执行起来,问题特别多。一个 400 行起步的 MR,评审人往往只来得及看两三个…

2026/10/19 13:51:40 阅读更多 →
从零配置Maven环境:避开JDK版本、settings.xml与依赖下载的坑

从零配置Maven环境:避开JDK版本、settings.xml与依赖下载的坑

上周帮A同学折腾新电脑,一天之内踩遍了配置 Maven 环境的所有经典坑:mvn 命令找不到、JAVA_HOME 路径不合法、依赖下载到一半卡死、IDEA 里构建正常但命令行一跑就报错。很多教程把 Maven 配置写成"下载解压、配两个变量、完事",但…

2026/10/19 13:51:40 阅读更多 →
SAP物料编号范围设计原理与实战配置指南

SAP物料编号范围设计原理与实战配置指南

简介:本资源是一份面向SAP ABAP开发人员、后勤模块顾问及系统实施工程师的实操型配置指南,聚焦物料主数据编号范围的后台维护方法与典型问题处理。针对ERP 6.0 EHP7版本,详细讲解如何通过MMNR/SNRO事务码创建号码组、定义内外部编号段&#x…

2026/10/19 13:51:40 阅读更多 →
LeetCode反转链表:迭代法详解与指针操作避坑指南

LeetCode反转链表:迭代法详解与指针操作避坑指南

1. 反转链表到底在反转什么 链表反转是LeetCode上出镜率最高的题目之一,没有之一。我刷了这么多题,面试里被问到的链表题,十道里有六道跟反转沾边——要么是完整反转,要么是反转前K个,要么是两两交换,要么是…

2026/10/19 13:51:40 阅读更多 →
MobileNetV2端到端部署实战:猫狗分类与模型量化

MobileNetV2端到端部署实战:猫狗分类与模型量化

1. 项目背景与技术选型思路一直在做端侧视觉类项目,说实话,猫狗图像分类这种题目听起来很“教学”,可真要把它做成一套能跑的轻量级系统,反而比想象中更能暴露问题。很多人一上来就往 VGG、ResNet 这种大模型上靠,训练…

2026/10/19 13:51:40 阅读更多 →
进口阀门选型与采购实务:极端工况应用与避坑指南

进口阀门选型与采购实务:极端工况应用与避坑指南

进口阀门这些年一直是工业项目里绕不开的话题。做设备采购的、搞工艺设计的、管工厂运维的,几乎都跟它打过交道。很多人一听到“进口阀门”就想到贵、货期长、售后麻烦,但实际上它能在国内重工业场景里占据一席之地,靠的是极端工况下那份稳定…

2026/10/19 13:50:38 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →