Struts 2 实战:老系统改造、拦截器链与避坑指南
简介这是一套基于Struts框架开发的企业级销售管理系统源码面向Java Web初学者与中级开发者聚焦MVC架构实践与销售业务建模能力提升。系统完整实现商品进出货管理含入库、出库、库存查询与盘点和客户管理含信息维护、分类评级、服务记录与关系维护两大核心模块可直接部署学习或二次开发。资源共298个文件涵盖94个JSP页面视图层、48个Java源码Action与DAO逻辑、48个Class字节码编译产物、35个JS脚本前端交互、20个JPG/PNG图片及18个CSS样式文件界面资源另有XML配置、字体与项目元数据文件整体压缩包仅2.05MB轻量易解压。已有258人下载学习适合通过真实业务场景理解Struts控制器调度、标签库应用、国际化支持及前后端协同机制尤其利于掌握商品-客户双主线的数据流设计与分层编码规范。1. 这不是又一个 CRUD 演示项目Struts 2 驱动的销售管理系统专治「改个字段要重发整包」的交付焦虑你手头正压着一个客户现场刚提的需求把“客户等级”从下拉单选改成带搜索的远程异步选择器后端要支持模糊匹配、分页、缓存穿透防护同时销售订单导出 Excel 的模板得加一列“最近一次回访时间”数据来自另一个微服务。你打开当前系统——一个用 Struts 2.3.x 搭建的老销售管理系统JSP 页面里混着 Java 脚本、Action 类里塞着 DAO 和业务逻辑、struts.xml 配置文件长达 800 行……改改完测试环境跑通UAT 环境报NullPointerException在getCustomerLevelList()的第 47 行不改客户下周就要验收。这不是教学 Demo这是某公司实际交付中反复翻车的真实战场。它用 Struts 2 作为核心 MVC 框架完整覆盖客户管理、商品维护、销售订单、库存查询、基础报表五大模块所有 Action 均通过 Convention 插件自动映射拦截器链明确分离权限校验、日志记录与事务控制。适合正在维护同类老系统的 Java 工程师、需要快速理解 Struts 2 实战边界的学生以及被“升级 Spring Boot”口号吓退、想先吃透经典分层设计的架构补习者。它不教你怎么写 Hello World它教你怎么在struts.xml里用result typeredirectAction安全跳转怎么让ModelDriven接口真正驱动页面绑定怎么用Validation注解替代 XML 验证配置——全是能立刻抄进自己项目里的硬货。2. 从源码结构到运行闭环Struts 2 销售管理系统的四层落地路径Struts 2 不是黑匣子它是一套有明确职责边界的分层契约。这个销售管理系统把这种分层具象化为可触摸的文件结构和可验证的调用链。我拆包后第一件事就是确认它是否真按 Struts 2 最佳实践组织——答案是肯定的src/main/java下清晰划分action、service、dao、model四包webapp/WEB-INF里struts.xml仅保留全局常量与包继承定义具体 Action 映射全部交给Namespace和Action注解驱动。这意味着你改一个订单查询逻辑不需要碰 XML 配置只要改OrderAction.java里的execute()方法和对应order.jsp视图即可。但前提是你得先让这个结构跑起来。2.1 环境准备JDK 8 Tomcat 8.5 是唯一经过验证的组合这个系统对 JDK 版本极其敏感。我试过用 JDK 11 启动Tomcat 日志第一行就报java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter——不是缺依赖是 Struts 2.3.34 内部反射调用 JAXB API而 JDK 11 已移除java.xml.bind模块。血泪经验必须用 JDK 8u202 或更高更新版但低于 8u301因后者引入了新的安全限制。Tomcat 必须是 8.5.x 系列推荐 8.5.999.x 会因 Servlet 4.0 的HttpServletResponse#sendError(int, String)签名变更导致StreamResult输出异常7.x 则因缺少AsyncContext支持使后台导出任务无法异步化。Maven 依赖里struts2-core版本锁死为2.3.34这是最后一个兼容 JDK 8 且修复了 OGNL 表达式沙箱绕过的稳定版。其他关键依赖版本如下依赖坐标版本作用说明org.apache.struts:struts2-core2.3.34核心 MVC 框架含拦截器、OGNL、结果类型org.apache.struts:struts2-convention-plugin2.3.34实现注解驱动 Action 映射省去 XML 配置org.apache.struts:struts2-json-plugin2.3.34提供json结果类型支撑 AJAX 异步交互org.hibernate:hibernate-core4.3.11.FinalORM 层与 Struts 2.3 兼容性最佳com.h2database:h21.4.199内置 H2 数据库开箱即用避免 MySQL 配置干扰提示不要试图升级struts2-core到 2.5.x。2.5 引入的SecurityMemberAccess机制会彻底禁用#context访问导致所有 JSP 中s:property value#session.user.name/全部失效且无平滑迁移方案。2.2 启动与验证三步确认 Struts 2 拦截器链已生效启动不是目的验证拦截器是否真实介入才是关键。很多开发者以为看到登录页就代表成功其实 Struts 2 的核心价值在请求处理管道里。我们用最朴素的方式验证# 第一步启动 Tomcat访问根路径 curl -I http://localhost:8080/sales/响应头中必须包含X-Struts-Executed: true—— 这是系统在struts.properties中配置的自定义响应头由ExecuteInterceptor添加证明 Struts 2 的执行拦截器已挂载。# 第二步触发一个带参数的 Action 请求如客户列表 curl http://localhost:8080/sales/customer/list.action?page1rows10检查 Tomcat 控制台日志应出现类似输出[INFO] [CustomerAction] - 开始执行客户列表查询参数page1, rows10 [DEBUG] [LoggingInterceptor] - 请求耗时127msURI/sales/customer/list.action [INFO] [TransactionInterceptor] - 事务已提交无异常这三行日志分别来自CustomerAction自身的log.info()、自定义LoggingInterceptor、以及TransactionInterceptor—— 证明拦截器链完整执行。2.3 关键配置解析struts.xml 与 struts.properties 的分工铁律这个系统把配置拆成两份是理解 Struts 2 设计哲学的钥匙。struts.xml只做三件事定义常量、声明包继承关系、配置全局结果。所有具体 Action 映射全部交给注解!-- struts.xml 片段 -- constant namestruts.devMode valuefalse/ constant namestruts.enable.DynamicMethodInvocation valuefalse/ package namedefault extendsstruts-default global-results result nameerror/common/error.jsp/result result namelogin typeredirectActionlogin_input/result /global-results /package而真正的路由逻辑在CustomerAction.java里Namespace(/customer) ParentPackage(default) public class CustomerAction extends ActionSupport implements ModelDrivenCustomer { Action(value list, results { Result(name success, location /customer/list.jsp), Result(name error, type chain, params {actionName, error_handler}) }) public String list() { // 查询逻辑 customerList customerService.findPage(page, rows); return SUCCESS; } }struts.properties则专注运行时行为# struts.properties 片段 struts.objectFactory spring struts.convention.action.packages com.example.sales.action struts.convention.result.path /WEB-INF/content/ struts.custom.i18n.resources global-messages这里struts.objectFactory spring是关键——它告诉 Struts 2所有 Action 实例交由 Spring 容器管理因此CustomerAction里可以直接Autowired private CustomerService customerService;无需手动new。而struts.convention.result.path指定了 JSP 视图的根路径所以Result(location /customer/list.jsp)实际解析为/WEB-INF/content/customer/list.jsp实现视图层隔离。3. 核心模块实战客户管理与销售订单的 Struts 2 编码范式Struts 2 的威力不在语法糖而在它如何把 HTTP 请求生命周期、Java 对象生命周期、Web 视图生命周期三者用一套拦截器契约粘合。客户管理模块是整个系统的入口销售订单模块则是业务复杂度峰值。我们以这两个模块为切口看 Struts 2 如何落地。3.1 客户管理ModelDriven 接口如何真正驱动双向绑定客户新增页面 (/customer/input.jsp) 使用标准 Struts 2 表单标签s:form actionsave methodpost s:textfield namename label客户名称 requiredtrue/ s:select namelevel list#{1:VIP,2:普通,3:潜在} label客户等级/ s:textarea nameremark label备注/ s:submit value保存/ /s:form关键在CustomerAction如何接收并校验这些参数。它没有用private String name;字段配 getter/setter而是实现了ModelDrivenCustomerpublic class CustomerAction extends ActionSupport implements ModelDrivenCustomer { private Customer model new Customer(); // 必须初始化 Override public Customer getModel() { return model; } Action(save) public String save() { // 此时 model.name, model.level, model.remark 已被自动注入 if (model.getName() null || model.getName().trim().isEmpty()) { this.addFieldError(name, 客户名称不能为空); return INPUT; // 返回 INPUT 结果重新渲染 input.jsp } customerService.save(model); return SUCCESS; } }ModelDriven的本质是Struts 2 在参数注入阶段会将所有namexxx的请求参数尝试设置到getModel()返回的对象属性上而非 Action 自身属性。这带来两个硬性要求第一model字段必须在 Action 构造时就初始化否则getModel()返回 null注入失败第二INPUT结果必须指向原始输入页这里是input.jsp因为 Struts 2 会自动将fieldErrors绑定到该页面的s:fielderror/标签上。如果你把INPUT指向其他页面错误信息就丢失了。3.2 销售订单JSON 插件与 AJAX 交互的防坑配置订单列表页需支持分页、排序、条件筛选全部通过 AJAX 加载。前端使用 jQuery$.post(/sales/order/list.action, { page: 1, rows: 20, sort: createTime, order: desc, customerName: $(#searchName).val() }, function(data) { renderTable(data.rows); // data 来自 JSON 插件序列化 });后端OrderAction的list()方法返回JSON结果类型Action(value list, results { Result(name success, type json, params { root, data, excludeProperties, data\\[\\d\\]\\.customer\\.orders|data\\[\\d\\]\\.items\\[\\d\\]\\.order, ignoreHierarchy, false }) }) public String list() { data orderService.findPage(page, rows, sort, order, customerName); return SUCCESS; }这里excludeProperties是生死线。data是一个MapString, Object其中data.get(rows)是订单列表ListOrder每个Order关联CustomerCustomer又关联ListOrder循环引用。若不排除JSON 插件会陷入无限递归最终StackOverflowError。excludeProperties的正则表达式data\\[\\d\\]\\.customer\\.orders精确匹配data[0].customer.orders这类路径阻止序列化。ignoreHierarchyfalse则确保只排除指定路径不连带排除父对象。3.3 权限拦截器基于 Session 的粗粒度访问控制实现系统未集成 Shiro 或 Spring Security而是用 Struts 2 自定义拦截器实现基础权限控制。AuthInterceptor.java核心逻辑public class AuthInterceptor extends AbstractInterceptor { Override public String intercept(ActionInvocation invocation) throws Exception { MapString, Object session invocation.getInvocationContext().getSession(); User user (User) session.get(user); if (user null) { // 未登录跳转至登录页但保留原请求 URL 用于登录后重定向 String requestUrl getRequestUrl(invocation); session.put(redirectAfterLogin, requestUrl); return login; // 全局 result name } // 检查角色简单字符串匹配生产环境应查 DB String actionName invocation.getProxy().getActionName(); if (actionName.startsWith(admin_) !ADMIN.equals(user.getRole())) { return forbidden; } return invocation.invoke(); // 放行 } }此拦截器在struts.xml中注册为默认拦截器栈interceptors interceptor nameauth classcom.example.sales.interceptor.AuthInterceptor/ interceptor-stack namedefaultStackWithAuth interceptor-ref namedefaultStack/ interceptor-ref nameauth/ /interceptor-stack /interceptors default-interceptor-ref namedefaultStackWithAuth/注意defaultStack已包含params、prepare、model-driven等核心拦截器auth必须放在最后确保model-driven已完成参数注入session已可用。4. 避坑指南Struts 2 销售管理系统上线前必踩的五个深坑Struts 2 的坑不在文档里而在你改了某行代码、重启 Tomcat、发现功能莫名失效的凌晨三点。以下是我在三个不同客户现场复现并解决的典型问题每一条都附带可验证的现象、根本原因和一行命令级解决方案。4.1 现象JSP 页面中s:property valuename/显示空值但System.out.println(name)打印正常原因name字段未遵循 JavaBean 规范。Struts 2 的 OGNL 表达式引擎要求若字段名为name则必须存在getName()方法且方法签名必须为public String getName()。如果误写为public String getname()小写 nOGNL 就找不到 getter返回 null。解决检查所有Action和Model类的 getter 方法命名用 IDE 的 “Generate Getter and Setter” 功能重新生成禁用手动编写。4.2 现象表单提交后addFieldError(name, 错误信息)不显示在页面上原因INPUT结果未正确指向原始输入页或输入页未包含s:fielderror fieldNamename/标签。更隐蔽的情况是struts.convention.result.path配置的路径与Result中location的相对路径计算错误导致 Struts 2 渲染了错误的 JSP而该 JSP 里没有fielderror标签。解决在struts.xml中临时添加constant namestruts.devMode valuetrue/启动后访问http://localhost:8080/sales/struts/查看“Configuration”页搜索INPUT结果对应的物理路径确认其与webapp/WEB-INF/content/下文件一致。4.3 现象AJAX 请求返回 500Tomcat 日志报ognl.MethodFailedException堆栈指向getText()方法原因getText(key)在 Action 中被调用时key对应的资源束global-messages.properties中该 key 不存在且struts.i18n.reload为true开发模式默认开启导致 Struts 2 尝试动态重载资源束失败。解决在struts.properties中添加struts.i18n.reloadfalse并将所有getText()调用包裹在 try-catch 中或改用getText(key, 默认文本)提供 fallback。4.4 现象H2 数据库中中文显示为乱码如“张三”存为“??”原因H2 连接 URL 缺少字符集参数。默认 JDBC URLjdbc:h2:~/salesdb不指定编码H2 使用平台默认编码Windows 通常是 GBK而 Struts 2 请求默认 UTF-8。解决修改hibernate.cfg.xml中的连接 URL 为jdbc:h2:~/salesdb;DB_CLOSE_DELAY-1;DB_CLOSE_ON_EXITFALSE;CHARSETUTF-84.5 现象部署到 Linux 服务器后s:file上传控件始终返回null本地 Windows 正常原因Linux 文件系统区分大小写而 Struts 2 的FileUploadInterceptor默认使用的临时目录java.io.tmpdir在某些 Linux 发行版中指向/tmp但struts.multipart.saveDir配置为upload相对路径导致 Struts 2 尝试创建/tmp/upload目录失败权限不足或路径不存在。解决在struts.properties中显式指定绝对路径struts.multipart.saveDir /var/tmp/sales-upload并确保该目录存在且 Tomcat 用户有读写权限sudo mkdir -p /var/tmp/sales-upload sudo chown tomcat:tomcat /var/tmp/sales-upload5. 进阶技巧用 Struts 2 拦截器链重构导出功能把 3 秒响应压到 300 毫秒销售系统最常被吐槽的点就是“导出 Excel 太慢”。原始实现是用户点击“导出”ExportAction.execute()方法内直接调用ExcelUtil.exportToResponse()遍历 10 万条订单逐行写入HttpServletResponse.getOutputStream()期间 Tomcat 线程被独占用户只能干等。这不是性能问题是架构问题——它把耗时 IO 操作塞进了 Struts 2 的同步请求处理链。真正的解法是用拦截器链把“触发导出”和“执行导出”彻底解耦。5.1 导出任务抽象从 Action 方法到独立 Service首先剥离导出逻辑。新建ExportService.javaService public class ExportService { // 使用 Spring 的 TaskExecutor 实现异步 Autowired private TaskExecutor taskExecutor; public void exportOrdersAsync(String condition, String userId) { taskExecutor.execute(() - { try { // 1. 查询数据此处用 Hibernate 分页避免内存溢出 ListOrder orders orderDao.findForExport(condition, 0, 100000); // 2. 生成 Excel 文件用 Apache POI SXSSFWorkbook 流式写入 File tempFile generateExcel(orders); // 3. 保存文件到共享存储如 NFS 或 MinIO生成下载 URL String downloadUrl saveToStorage(tempFile, userId); // 4. 更新用户通知表标记任务完成 notifyService.sendComplete(userId, downloadUrl); } catch (Exception e) { notifyService.sendFail(userId, e.getMessage()); } }); } }5.2 拦截器接管ExportTriggerInterceptor 实现零侵入触发新建拦截器ExportTriggerInterceptor.java它不处理业务只做一件事当检测到请求参数含exporttrue就调用ExportService并立即返回轻量 JSONpublic class ExportTriggerInterceptor extends AbstractInterceptor { Autowired private ExportService exportService; Override public String intercept(ActionInvocation invocation) throws Exception { MapString, Object params invocation.getInvocationContext().getParameters(); if (params.containsKey(export) true.equals(params.get(export).toString())) { // 提取导出条件从 request 参数或 session 中获取 String condition extractCondition(invocation); String userId getCurrentUserId(invocation); // 异步触发导出 exportService.exportOrdersAsync(condition, userId); // 立即返回成功响应前端轮询状态 HttpServletResponse response ServletActionContext.getResponse(); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\status\:\success\,\message\:\导出任务已提交请稍后查看通知\}); return NONE; // 不走后续拦截器和 Action直接结束请求 } return invocation.invoke(); // 正常流程 } }5.3 前端协同轮询 通知中心用户体验质变前端不再等待导出完成而是点击“导出”按钮发送POST /order/list.action?exporttruecustomerNameABC收到{status:success}后隐藏按钮显示“导出任务已提交”启动轮询GET /notify/status.action?userId123检查通知表一旦返回{status:complete, url:/download/20240520-123456.xlsx}弹窗提示并提供下载链接。这个方案把用户感知的“等待时间”从 3 秒降为 300 毫秒纯网络往返而真正的耗时操作在后台静默执行。更重要的是它完全不修改任何原有 Action 代码——OrderAction.list()方法依然只负责查数据、返回 JSONExportTriggerInterceptor作为独立拦截器插入到defaultStack之前实现关注点分离。从那以后我每次接到“导出慢”的需求都不再碰Action类而是先画一张拦截器链图哪里该切、哪里该异步、哪里该降级。Struts 2 的拦截器不是装饰器它是请求生命周期的手术刀。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Unity预制体实例与磁盘存在性三重判定解析

Unity预制体实例与磁盘存在性三重判定解析

1. 项目概述:为什么在Unity里揪出“真预制体”比想象中更难在Unity项目开发的中后期,尤其是多人协作、模块化开发或热更新架构下,“这个对象到底是不是预制体”这个问题,几乎每天都会被问到三次以上。我见过太多团队因为没搞清一个…

2026/10/15 0:44:39 阅读更多 →
OLAP数据立方体增量更新技术与实践

OLAP数据立方体增量更新技术与实践

1. OLAP数据立方体增量更新的核心价值在传统数据分析场景中,每次数据变动都需要全量重建数据立方体(Data Cube),当数据量达到TB级别时,这种操作会消耗数小时甚至数天的计算资源。我曾在金融行业的数据仓库项目中&#…

2026/10/15 0:43:39 阅读更多 →
域环境中 LDAP 查询技巧,不用工具手工搜集域资产

域环境中 LDAP 查询技巧,不用工具手工搜集域资产

🔒免责声明:本文内容仅用于授权渗透测试、红蓝对抗、安全运维学习研究,仅可在自己拥有书面授权的靶场环境执行操作,未经授权访问、查询企业域资产属于违法行为,请遵守网络安全相关法律法规。 前言 做域渗透信息收集的…

2026/10/15 0:43:39 阅读更多 →

最新新闻

从源码编译GMSSL:国密算法支持与HTTPS链接调试实战

从源码编译GMSSL:国密算法支持与HTTPS链接调试实战

1. 从源码到动态库:为什么选择自己编译GMSSL很多人第一次接触国密算法开发时,第一反应是找现成的二进制包或者系统自带的包管理器直接安装。这个思路在大多数场景下没问题,但一旦涉及国密算法,情况就完全不一样了。GMSSL作为国内广…

2026/10/15 2:46:27 阅读更多 →
SpringBoot+Vue学院管理系统开发实战

SpringBoot+Vue学院管理系统开发实战

1. 项目概述与适用场景这个基于SpringBootVue技术栈的学院个人信息管理系统,是典型的教学级全栈开发项目。我在高校信息化部门工作期间,曾主导开发过类似系统,也指导过多名学生完成此类毕业设计。这类系统之所以成为热门选题,关键…

2026/10/15 2:46:27 阅读更多 →
SpringBoot+Vue高校医务室预约管理系统设计与实践

SpringBoot+Vue高校医务室预约管理系统设计与实践

1. 项目背景与核心价值高校医务室作为校园健康保障的第一道防线,长期面临着就诊高峰期排队混乱、病历管理低效、健康数据分散等痛点。这个基于SpringBootVue的预约管理系统,正是为了解决这些实际问题而设计的数字化解决方案。我在参与某高校医疗信息化改…

2026/10/15 2:46:27 阅读更多 →
医疗陪诊小程序开发:功能架构与技术实现详解

医疗陪诊小程序开发:功能架构与技术实现详解

1. 陪诊小程序的市场需求与产品定位医疗陪诊服务正在成为城市生活中的刚需。根据我过去三年参与医疗信息化项目的经验,独居老人、术后康复患者、异地就医人群构成了核心用户群体。这类用户往往面临"挂号难""流程陌生""行动不便"三大痛…

2026/10/15 2:46:27 阅读更多 →
KingdeeERP插件开发实战:从入门到精通

KingdeeERP插件开发实战:从入门到精通

1. 项目概述KingdeeERP作为国内主流的企业管理软件,其插件开发能力为系统功能扩展提供了强大支持。作为一名在ERP领域深耕多年的开发者,我见证了从K/3到Cloud版本的技术演进过程。插件开发不仅仅是简单的功能叠加,更是对企业业务流程的深度定…

2026/10/15 2:46:27 阅读更多 →
Flutter 欢迎页实战:用 intro_slider 构建引导页并实现「只显示一次」的路由跳转(Flutter-Notebook slider_screen 示例解析)

Flutter 欢迎页实战:用 intro_slider 构建引导页并实现「只显示一次」的路由跳转(Flutter-Notebook slider_screen 示例解析)

示例工程移动开发 【免费下载链接】Flutter-Notebook FlutterDemo合集,今天你fu了吗 项目地址: https://gitcode.com/gh_mirrors/fl/Flutter-Notebook 点击查看 免费下载 本文以 Flutter-Notebook 仓库中 mecury_project/example/slider_screen 示例为核…

2026/10/15 2:45:27 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →