news 2026/10/21 20:00:35

JSP家庭作业管理系统:从源码到部署的Java Web实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JSP家庭作业管理系统:从源码到部署的Java Web实战解析

JSP家庭作业管理系统:从源码到部署一次讲透

这段时间我在梳理一个JSP家庭作业管理系统,从数据库设计到页面渲染,再到Tomcat底下调通整个链路,过程相当折腾,也相当过瘾。这个项目把Java Web开发最经典的组件挨个用了一遍——JSP、Servlet、JDBC、MySQL、Tomcat,覆盖面广,难度适中,特别适合正在做课程设计、或者刚接触Java Web想找个完整项目练手的朋友。这篇文章我打算把整个项目从需求拆解到调试部署完完整整讲一遍,包括每张表为什么这么建、每个Servlet的权限校验怎么设计、部署时中文字符集怎么一次配到位,这些都踩过坑,也都有现成经验可以直接抄。

总结一下这个系统到底能干什么:老师登录后发布作业、设置截止时间、查看提交列表并打分;学生登录后查看作业清单、在线提交文字内容和附件、查看批改结果。加上账号管理、权限控制、按作业统计提交率这些辅助功能,一套师生间作业流转的闭环就完整了。适合学习参考的人分两类:一类是自己做SSM或Spring Boot项目做腻了,想回头补补底层基本功的开发者;另一类是刚开始接触Java Web,想找一个结构清晰、没有过度封装的项目入门的同学。

1. 项目整体设计与核心思路

1.1 为什么选JSP技术栈

这几年Spring Boot加Vue前后端分离几乎成了默认选项,JSP这个技术栈确实显得有点“老”。但为什么这个项目还要用JSP来写?我先把话放这儿:技术选型没有绝对的新旧,只有合不合适。

JSP最大的特点就是服务端渲染,浏览器拿到的页面是服务器直接拼好的完整HTML,不需要前端工程化那套Node、Webpack、Proxy配置。对于一个用户量不大、业务逻辑清晰的课设或内部系统,这意味着开发环境极其简单——装个JDK、解压一个Tomcat、连上MySQL,半小时就能开始写代码。反过来如果用Spring Boot加Vue,光是把前端工程跑起来、处理跨域请求、维护两套代码,投入的精力就翻倍了。

从学习价值来看,JSP加Servlet的组合能让人把HTTP请求的完整生命周期看得明明白白。请求进来先找Servlet,Servlet调DAO层访问数据库,拿到结果再forward到JSP渲染——这个链路几乎没有隐藏的封装。Spring MVC里一个@Controller加几个注解就搞定了,但注解背后发生了什么,新手在黑盒阶段是很难想明白的。我见过太多人写Spring Boot项目能跑,但问他Servlet生命周期、请求响应流程,答不上来。JSP项目恰恰能补上这块基本功。

1.2 家庭作业管理系统的需求拆解

这个系统表面看功能不多,但真拆起来,它的业务逻辑分三大块:用户管理、作业流转、数据统计,每一块都有对应的设计约束。

用户管理很简单,两个角色:老师和学生。老师有工号、姓名、院系这些信息,学生有学号、姓名、班级信息。每个人都能登录、修改个人密码,这是最基础的功能。

作业流转是系统的心脏。老师要能发布作业,填写标题、详细要求、截止时间;学生要能看到作业列表,点进详情后提交回答,可以填文字,也可以传附件;老师还要能查看某份作业的所有提交记录,逐个给分数、写评语。这个环节涉及一个关键设计问题:权限校验。学生只能看作业和提交作业,绝对不能有修改或删除作业的按钮;老师只能管理自己发布的作业,不能改别的老师的内容。这些限制在Servlet里必须有硬校验,不能只靠前端把按钮隐藏掉——当年我做第一个Web项目时,以为按钮隐藏了就算权限控制,结果直接把URL后缀改一下,就能以学生身份调老师的管理接口,数据被改得乱七八糟。那是很深刻的一课。

数据统计是加分项。我建议至少实现两个维度的统计:按作业统计提交率和平均分,按学生统计已提交作业数和平均成绩。这两个查询写起来不复杂,主要是SQL里的表连接和分组聚合,但对老师的日常管理特别实用。

权限矩阵这个东西,我强烈建议在做页面之前先把表画出来。横轴是操作(查看作业、发布、修改、删除、提交),纵轴是角色(管理员、老师、学生),每格标上允许或禁止,后面写Servlet逻辑时就不会漏。我在这个项目里把权限校验封装成了一个工具类,在Service层统一调用,比在Servlet里到处写if判断要省心得多,后续加新功能也不用担心忘记校验权限。

2. 数据库设计与核心表结构

2.1 数据实体分析与建模

数据库设计是整套系统的地基,它比代码更值得花时间。如果表结构设计错了,后面写多少行代码都是在错误的基础上打补丁。我最终定的方案是四个表:student(学生表)、teacher(教师表)、homework(作业表)、submission(提交记录表)。

整个系统的枢纽是submission表。它同时关联homework_id和student_id,记录的是“某个学生对某份作业的提交情况”——包括提交文字、附件路径、提交时间、批改分数和教师评语。为什么批改分数要放在submission而不是homework?这个问题我每次都会问身边的人。答案很简单:分数是依附于“提交”这个行为存在的,一个学生对一份作业交了一次才会有成绩。作业表本身存的应该是标题、内容、截止时间这些公共属性,如果往作业表里塞分数字段,那十个人交作业就得十行记录,逻辑就乱套了。

下面是四张表的字段清单,照着建就可以:

student表:id(主键自增)、student_no(学号,唯一索引)、name、password(MD5加盐后存储)、email、phone、class_name(班级)、create_time(默认当前时间)

teacher表:id(主键自增)、teacher_no(工号,唯一索引)、name、password、department(所属院系)、email、create_time

homework表:id(主键自增)、teacher_id(外键关联teacher表)、title、content(作业要求,TEXT类型)、deadline(截止时间,DATETIME)、create_time、update_time

submission表:id(主键自增)、homework_id(外键)、student_id(外键)、content(提交的文字)、file_path(附件在服务器上的相对路径)、submit_time、score(TINYINT,0到100)、remark(教师评语)

有两个字段设计上的细节我必须单独拎出来说。第一个是password字段,明文存储是底线问题,一定不能干。我用了MD5加盐的方式,即使数据库被拖库,密码也不是直接暴露的。第二个是deadline,一定用DATETIME类型,不要用VARCHAR。用了DATETIME,判断“作业是否已过期”就只需要一条SQL:WHERE deadline > NOW(),数据库自己就能算;用VARCHAR就得先把字符串解析成时间对象,费力而且容易出错。

2.2 关键SQL与增删改查实现

增删改查是每个系统都绕不开的基础操作,但在这个项目里有几个点需要特别注意写法。

先看插入作业的SQL:

INSERT INTO homework (teacher_id, title, content, deadline) VALUES (?, ?, ?, ?)

这里必须用PreparedStatement而不是Statement。最直接的原因是防SQL注入。如果你把用户输入的标题直接拼进SQL字符串:INSERT INTO homework ... VALUES (1, '" + title + "', ...),那用户在标题框里输一段 "x'); DROP TABLE homework; --",数据库就能把整张作业表删了。PreparedStatement先预编译SQL模板,参数通过占位符传进去,数据库把这些值当纯数据处理,注入就没有了生存空间。这个问题的原理我用一句话跟新人解释:SQL注入的本质是把“代码”和“数据”混在了一起,预编译就是强制把两者分开。

查询作业列表的SQL涉及表连接和排序:

SELECT h.*, t.name AS teacher_name FROM homework h LEFT JOIN teacher t ON h.teacher_id = t.id ORDER BY h.deadline ASC

这里为什么用LEFT JOIN而不是INNER JOIN?理论上homework表里每条记录的外键teacher_id都应该在teacher表里存在,INNER JOIN就够了。但实际项目里难免遇到脏数据——比如老师账号被删了但作业还在,这时候INNER JOIN会把这条作业记录直接过滤掉,学生端就看不到这份作业了。用LEFT JOIN则保证作业记录始终出现在结果集里,即使教师信息为NULL,至少能显示“未知教师”。这个选择本质上是在T资历、健壮性和结果的严谨性之间做一个取舍。

更新作业的动态SQL是个容易被忽视但也容易被骂的需求。老师编辑作业时,有可能只改标题,有可能只改截止时间。如果每次更新都把四个字段全部SET一遍,那用户没动过的字段也会被覆盖回空值。我在DAO层的update方法里做了字段非空判断,哪些参数不为空,就拼接哪些SET子句。代码量是多了一点,但换来了正确的用户体验,值得。

删除作业我用的是物理删除,原因很朴素:作业过期了确实没人看,空间不值得留。但删作业时有一个必须处理的连锁反应——submission表里所有关联这条作业的提交记录都会变成孤儿数据,查询时会出现一堆外键悬空。我在建表时给外键加了ON DELETE CASCADE,数据库层面自动级联删除。如果不想删提交记录(比如要保留统计数据),那就得改成逻辑删除,给homework表加一个is_deleted字段,查询时统一过滤。这个开关我在源码里做了配置,默认走物理删除。

3. 开发环境搭建与源码结构

3.1 开发环境选型和配置

环境搭建看着简单,其实是整条链路里最容易卡住新手的地方。我先把这套项目跑通所需的环境列成表,照着配就行:

组件推荐版本备注
JDK1.8(JDK 8)最稳,兼容性最好
Tomcat8.5或9.0对应JDK 8,Servlet版本3.1
MySQL5.7或8.08.0需注意驱动和URL配置
IDEIntelliJ IDEA或Eclipse看个人习惯
构建工具Maven管理依赖、打包WAR

JDK和Tomcat的版本配套问题,是我反复强调的高频坑。JDK 8配Tomcat 8.5毫无问题,但如果你装的是JDK 17,Tomcat就得用10.x,而Tomcat 10引入了Jakarta命名空间,原来代码里的javax.servlet全部要改成jakarta.servlet,一个JSP旧项目的import语句会全线报红。很多新手第一步就栽在这里,项目跑不起来还以为是代码问题,其实换成JDK 8加Tomcat 8.5就全通了。

数据库驱动也有版本讲究。MySQL 5.7用mysql-connector-java 5.1.x,MySQL 8.0则得用mysql-connector-j 8.x,驱动类名从com.mysql.jdbc.Driver变成了com.mysql.cj.jdbc.Driver,而且连接URL后面要追加serverTimezone=Asia/Shanghai。如果你连的是MySQL 8.0却用老驱动,启动时大概率会看到关于Public Key Retrieval的异常。这个我在第5章展开讲。

3.2 源码目录结构与关键模块

拿到这套源码之后,先别急着点运行,花十五分钟把目录结构看懂,后面调试会顺畅得多。标准JSP分层项目的结构是这样组织的:

src目录下面按包组织代码。entity包放实体类,对应四张表的Java对象;dao包放数据访问类,负责和数据库交互;servlet包放控制器,接收请求、调服务、转发页面;util包放工具类,比如MD5加密、日期处理;filter包放过滤器,处理全站点编码和登录校验。

WebContent目录下是JSP页面和配置文件。web.xml是部署描述符,Servlet、Filter、欢迎页都在这里面注册;页面按目录组织,比如student和teacher两个文件夹,把不同角色的页面分开,看着清楚,也防止误访问。

这套源码里我最想夸奖的是DAO层的设计。BaseDAO类封装了最核心的四个通用方法:getConnection()获取连接、executeQuery()执行查询并返回结果集、executeUpdate()执行增删改、close()统一释放资源。子DAO继承BaseDAO后,各自的增删改查只需要聚焦SQL语句和参数映射,不用每次重复写获取连接、关闭连接这些样板代码。这个模式虽然简单,但它是很多框架里ORM映射的雏形,理解了这个,后面再学MyBatis会轻松很多。

数据库连接层面也有一个容易被忽略的性能优化点。很多初学代码是每个请求都new一个Connection,用完再close。这个写法在开发环境问题不大,但部署到服务器上一旦并发量上来,MySQL的连接数会被瞬间打满,报出Too many connections错误。源码里用的是DBCP连接池技术,在项目启动时预创建一批连接放池子里,请求来了借一个,用完了还回去。这个优化对并发场景是质变级的,建议保留不要删掉。原理就类比成:你不可能每次做饭都先种地,得提前把米备好放锅里。

web.xml里面注册的CharacterEncodingFilter过滤器也是关键。它的作用是把请求和响应统一设置为UTF-8。没有这个过滤器,GET和POST请求的中文参数在Tomcat默认的ISO-8859-1编码下必然变成乱码;有了它,开发环境基本就不会再被中文乱码困扰。部署到服务器后,还要配合Tomcat的server.xml里Connector加URIEncoding="UTF-8",两边一致才能全面兜住编码问题。

4. 核心功能实操与实现细节

4.1 作业发布与提交模块

作业发布是老师端使用频率最高的功能,它的实现思路很有代表性。老师进入发布页面,填标题、内容、截止时间三个必填项,表单提交到Servlet。Servlet要做的事分三步:首先从Session中取出当前登录的teacher对象,拿到teacherId;然后调用HomeworkDAO的insert方法,把数据写进homework表;最后重定向回作业列表页。

这里有一个必须解释清楚的设计细节:为什么用sendRedirect重定向,而不是request.getRequestDispatcher().forward()转发?原因在于重复提交。如果用forward,浏览器地址栏不会变化,用户操作完看到列表页,按F5刷新,浏览器会重新提交上一次的表单请求,结果同一份作业被插入了两次。而sendRedirect是让浏览器重新发起一次全新的GET请求,用户再怎么刷新,触发的是GET请求而不是原来的POST,重复提交问题从根上就规避了。这就是Web开发里常说的POST-Redirect-GET设计模式,值得绝大多数增删改场景遵循。

学生提交作业这块,有一个环节容易在验收时翻车:表单里的附件上传。表单的enctype必须设置为multipart/form-data,否则浏览器只会提交文件名,不会传文件内容。Servlet端接收文件时,源码用的是Servlet 3.0的Part接口,核心代码大致这样:

Part part = request.getPart("file"); String fileName = part.getSubmittedFileName(); String savePath = uploadDir + File.separator + fileName; part.write(savePath);

文件写入服务器磁盘的指定目录后,不要直接把绝对路径存进数据库。原因很简单:绝对路径绑定了当前服务器的磁盘结构,以后换服务器、换目录,路径就全失效了。源码里存的是相对路径,比如uploads/20250612_hw3_student5.pptx,页面展示时再拼上项目根路径。这样部署环境换了,只要把上传目录一起迁移,路径逻辑就不用动。

兼容性提醒一下:Part接口是Servlet 3.0规范引入的,要求Tomcat 7+。如果服务器是Tomcat 6或更老,就得换用Apache Commons FileUpload组件来解析multipart请求。部署前务必确认Tomcat版本,这个坑我在第5章细聊。

4.2 个人信息展示页与成绩查询实现

“JSP个人信息展示页面”这个话题在最近的社区讨论里热度挺高,因为很多人的JSP页面写法不规范。我见过有人在JSP页面里直接写大量Java代码块输出用户信息,页面能跑,但维护体验极其糟糕——改个样式还得小心不要破坏Java逻辑。

规范的做法是MVC思路。Servlet从数据库查出当前登录用户的完整信息,把用户对象塞进request作用域,然后转发到JSP页面。JSP页面里用EL表达式和JSTL标签来输出属性,页面代码保持干净。EL表达式的核心写法是:

${sessionScope.user.name} ${sessionScope.user.email}

这里特别提醒一下sessionScope前缀的作用。如果不写作用域前缀,JSP容器会按page到request到session到application的顺序逐个查找同名属性。虽然最终大概率能查到,但每次都要做无用遍历;更关键的是,如果不同作用域里存在同名变量,不写前缀就是告诉程序“哪个都行”,取到的结果可能完全不是你想的那个。写清楚数据来源,既省事又避错。

成绩查询是整个项目里业务逻辑最丰富的模块,原因在于两种视角完全不同,但都要在同一套表结构里完成查询。学生视角是“我交了哪些作业、每份得了几分”,SQL需要把submission表关联homework表和学生表,条件里用当前登录学生的studentId过滤。教师视角则是“某份作业所有学生的提交情况和分数”,SQL条件是submission.homework_id等于指定的作业ID,再做按学生分组。

两个视角对应同一个Servlet下的两个业务方法,各自封装SQL查询。代码写完后记得在效果上验证一遍:学生端登录后,只能看到自己的提交和成绩;教师端登录后,选择某份作业能看到全部提交列表。两边的数据不能交叉,这是权限控制的底线。

5. 调试部署全过程实录

5.1 本地调试的主要坑

把项目导入IDE之后,真正的战斗才刚开始。本地调试阶段我踩过的坑不少,在这里挑三个最典型的展开,给大家当作排查手册用。

第一个是JSP页面报“Unable to compile class for JSP”。这个报错看起来像是代码编译错误,实际上九成是JDK和Tomcat版本不匹配导致的。JSP编译器找不到合适的javac接口时就会抛出这个异常。解决方案我前面也说过:把JDK降回8、Tomcat用8.5,这是最稳妥的组合。如果非要保留新JDK,就得接受Tomcat 10的Jakarta命名空间改动,把大量import语句从javax.servlet改成jakarta.servlet。两条路都能走通,但明显第一条省事。

第二个是访问数据库时报“Public Key Retrieval is not allowed”。这个问题只出现在MySQL 8.0加新版驱动组合下,原因是MySQL 8.0默认用caching_sha2_password认证方式,客户端第一次连接时需要先从服务器获取公钥来加密密码。解决办法有两个:一是连接URL追加allowPublicKeyRetrieval=true&useSSL=false参数,开发环境图省事用这个;二是把数据库用户的认证插件改回mysql_native_password,生产环境建议用这个更安全。

第三个是上传文件时中文文件名乱码。浏览器提交的文件名是UTF-8编码,但Servlet获取参数时默认按ISO-8859-1解码,结果就是中文名彻底乱掉。修复方法是在获取文件名后做一个转码:

String fileName = part.getSubmittedFileName(); fileName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");

这个写法的原理其实很直观:先把按ISO-8859-1解码得到的字符串重新变回原始字节,再用UTF-8去解码,中文就还原回来了。要是这样处理完还乱,那就要检查Tomcat的server.xml里Connector节点是否设置了URIEncoding="UTF-8",这一项缺了,GET请求的参数一样会乱。

5.2 服务器部署与数据库同步

本地调通了,剩下就是把项目送到服务器上真正跑起来。JSP项目的部署流程非常标准,本质还是三步:打包WAR、放到Tomcat的webapps目录、导入数据库。

打包用IDE导出或Maven执行mvn clean package,生成一个WAR文件。WAR包放到Tomcat的webapps目录后,启动Tomcat会自动解压部署。这里有个小知识点容易被忽略:WAR包的文件名决定了应用的访问路径。比如homework.war部署后,访问入口就是http://服务器IP:8080/homework/xxx,如果改个名字,路径也跟着变。

数据库导入这一步风险点也不少。本地MySQL导出的SQL文件,在服务器上执行时经常因为字符集不统一导致乱码。我在导入前习惯先给SQL文件头部加上两句:

SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;

第一句的作用是明确客户端使用的字符集,确保中文字符写入数据库时不被转义;第二句是临时关闭外键检查,防止因为表导入顺序问题导致外键创建失败。等数据全部导完,再手动开启外键检查,安全又省事。

现在有朋友会问到“数据库同步软件”的问题。我理解这里说的同步,是指开发环境数据库和线上数据库的一致性维护问题。对于这个项目体量,完全不需要引入专门的数据同步工具,用mysqldump命令就足够了:

mysqldump -u root -p homework_db > homework_backup.sql mysql -u root -p homework_db < homework_backup.sql

第一行是导出备份,第二行是导入恢复。数据量到几百MB这个级别,再用Navicat的数据传输功能或MySQL Workbench来同步,日常维护完全够用。

6. 常见问题与排查速查表

6.1 典型报错及处理实录

把调试部署过程中遇到的常见报错整理成一张速查表,方便大家直接对照:

报错信息或现象出现原因解决方法
JSP无法编译 / 500 ClassNotFoundJDK与Tomcat版本不匹配统一用JDK 8 + Tomcat 8.5
中文乱码(数据库和页面)字符集配置不全项目用UTF-8、Tomcat配置URIEncoding、数据库用utf8mb4
数据库连接超时 / Too many connections每次请求新建连接改用连接池(DBCP/C3P0)
提交作业后刷新出现重复数据用了forward转发未重定向改用sendRedirect实现PRG模式
文件上传后中文名乱码编码解码不一致ISO-8859-1转UTF-8
登录成功却跳回登录页Session丢失或Filter放行逻辑不对检查Session有效期、Filter的放行规则

这张表里的每一条,都是真实项目里验证过的场景,直接复制到自己的排查手册里用就行。

6.2 避坑经验和技巧

最后聊几段实操过程中最有价值的经验。这些内容不一定写在官方文档里,但真能帮人省下大把时间。

第一个是日志输出贯穿始终。调试JSP项目时,很多人依赖System.out.println,但这招在并发场景下很容易打乱输出顺序,有时候压根定位不了问题。建议哪怕不用log4j这种重型日志框架,也要用java.util.logging做结构化日志,在DAO层和Servlet关键方法入口打上参数和耗时,排查效率能翻倍。我在这个项目里用log4j,每个增删改查方法的前后都有日志,后面看到某个功能慢,直接翻日志就能确认是SQL查询慢还是页面渲染慢。

第二个是IDE的参数配置。Eclipse里跑Tomcat时控制台输出偶尔乱码,需要在Run Configurations的VM arguments里加一行-Dfile.encoding=UTF-8。IntelliJ IDEA则需要在Help菜单的Edit Custom VM Options里加同样的参数。Windows环境下的中文乱码问题,十个有九个就是缺了这个参数。

第三个是初始化流程脚本化。我把四张表的结构定义、初始测试数据、默认账号全部整理到一个init.sql文件里,再配一个一键执行的shell脚本或bat脚本。这样一来,换电脑、换环境、把项目交给别人的时候,只需要跑一次脚本就能把数据库初始化好,不用再手动一条条建表插数据。这个小习惯在团队协作里性价比极高。

第四个是把敏感配置外置。数据库的连接地址、用户名、密码不要写死在Java代码里,统一放在db.properties配置文件中,用java.util.Properties类来加载。拿到这个项目部署到生产环境,只需要改配置文件,不用动代码重新编译。我见过不少人把账号密码直接写在JDBC工具类里,结果每次换环境都要重新打包,一旦忘记改,连的就是错误数据库,排查半天才发现是配置没换。

再补一个不太明显但很隐蔽的坑:JSP页面里尽量不要残留直接用<%= %>输出数据的Java脚本片段。这套源码有一部分页面已经改成了EL和JSTL,但仍有老页面是脚本式写法。如果准备二次开发,建议把所有页面的脚本表达式逐步替换成EL表达式,页面会干净很多,后期维护的心情也会好很多。


这个项目完整走下来,相当于把Java Web开发的全链路摸了一遍:从需求分析到数据库设计,从开发环境搭到线上部署,从增删改查到权限控制,每一步都有直观的代码和运行结果对应。我个人的体会是,这类JSP项目虽然技术栈不算前沿,但它把Servlet生命周期、JDBC细节、数据库设计规范和部署流程这些最底层的基本功打磨得很扎实。现在不少人一上来就学Spring Boot,注解一堆但底层一头雾水,回头补一个JSP项目,反而能把前后知识串成一条线。

如果后续有精力做扩展,方向也很多:给系统挂上真正的文件存储服务、用ECharts把成绩统计图做出来、把登录升级成邮箱验证码方式。每个方向都能延伸出不少有价值的内容。

最后再分享一个小技巧:拿到这套源码准备二次开发时,先从数据库入手,把四张表的字段含义理清楚,再去看DAO层,最后才看Servlet和JSP。数据结构清楚了,代码逻辑基本就顺了。千万不要一头扎进JSP页面去改前端,搞不清数据从哪里来,越改越乱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 16:27:25

JMeter二次开发实战:自定义函数解决动态签名与参数处理

压测做久了&#xff0c;你会发现真正折磨人的往往不是并发量&#xff0c;而是请求参数本身。JMeter自带的那套函数库&#xff0c;平时用着还行&#xff0c;一旦遇到“每个请求都要动态算签名”“按业务规则生成一批特定手机号”“从响应里取出来的值还得做二次编码”这类场景&a…

作者头像 李华
网站建设 2026/10/16 8:08:55

5个轻量级Pi开源工具:提升开发者日常效率的终端瑞士军刀

1. 项目概述&#xff1a;为什么这5个Pi开源扩展值得你花30分钟装上“Pi”这个字眼在当前技术圈里&#xff0c;已经悄然脱离了数学常数的单一语境&#xff0c;演变成一个轻量、可嵌入、面向边缘与个人开发者的工具代称——它不指代某款硬件&#xff0c;而是一类以极简架构、低资…

作者头像 李华
网站建设 2026/10/20 22:24:12

Codex一直显示“正在思考”?WebSocket握手失败与HTTPS回退全解析

最近被 Codex 折腾了一把——对话框里一直显示“正在思考”&#xff0c;转圈转到天荒地老&#xff0c;既没有报错也没有结果。这不是网络慢的问题&#xff0c;排查到最后发现&#xff0c;真正的原因藏在 WebSocket 连接上&#xff1a;客户端尝试用 WebSocket 做流式请求&#x…

作者头像 李华
网站建设 2026/10/17 18:39:55

MediaGo流媒体下载:从HLS分段解析到30MB/s极速保存

流媒体时代&#xff0c;很多人都有这样的经历&#xff1a;刷到一个收藏级的公开课视频&#xff0c;看完一遍不过瘾&#xff0c;想转存到本地慢慢品&#xff1b;或者自己付费订阅了某个在线学习平台&#xff0c;会员到期之前想把课程备份下来&#xff0c;却发现平台只给了"…

作者头像 李华
网站建设 2026/10/16 11:44:51

Notepad++ 写 Markdown 实战:插件安装、预览配置与避坑指南

简介&#xff1a;这份资源面向使用 Notepad 编写 Markdown 文档的开发者与技术人员&#xff0c;解决编辑器原生不支持 Markdown 语法高亮与实时预览的问题。压缩包内共 2 个文件&#xff0c;包含 1 个 dll 插件核心组件与 1 个 xml 语言配置文件&#xff0c;整体约 228KB&#…

作者头像 李华
网站建设 2026/10/20 3:31:43

mysqld --initialize --console 初始化失败原因排查与解决清单

很多人在装 MySQL 5.7 或 8.0 时&#xff0c;第一次执行mysqld --initialize --console就卡住了&#xff0c;要么窗口一闪而过&#xff0c;要么终端里抛出一堆[ERROR]&#xff0c;翻来覆去查不清楚到底是哪里的问题。这条命令本身不复杂&#xff0c;但它牵扯到目录状态、文件权…

作者头像 李华