1. 泛微E9二次开发环境搭建全攻略第一次接触泛微E9的开发者环境搭建绝对是第一个拦路虎。我见过太多人在这个环节浪费好几天时间最后发现是数据库配置文件没改对。下面就把我这些年总结的环境搭建经验分享给大家。本地测试环境搭建最关键的三个步骤代码拷贝、数据库配置、依赖检查。先从服务器把WEAVER/ecology目录完整拷贝到本地记得Resin和JDK也要一并带上。我习惯放在D:/WEAVER目录下这样路径短不容易出错。数据库配置是新手最容易栽跟头的地方。配置文件在/ecology/WEB-INF/prop/weaver.properties这里有个血泪教训一定要把数据库连接改成测试库去年有个同事不小心连到了生产库差点引发重大事故。不同数据库的配置模板如下# SQLServer配置示例 DriverClassescom.microsoft.sqlserver.jdbc.SQLServerDriver ecology.urljdbc:sqlserver://localhost:1433;DatabaseNameecology_test ecology.usersa ecology.passwordyourpassword # Oracle配置示例 DriverClassesoracle.jdbc.OracleDriver ecology.urljdbc:oracle:thin:localhost:1521:ecology ecology.usertest ecology.passwordtest123开发工具推荐使用Eclipse或IntelliJ IDEA。需要特别注意JDK版本兼容性问题E9通常需要JDK1.8。我建议在IDE里配置好Maven把ecology/lib下的jar包都添加到项目依赖中。遇到过最坑的问题是缺少xercesImpl.jar会导致XML解析异常。2. 核心模块开发实战技巧2.1 流程引擎深度开发流程开发是E9最核心的功能。理解清楚workflow_*系列表结构是基础比如workflow_base存储流程定义workflow_requestlog记录审批意见。我建议先在数据库里把这些表的关系理清楚。自定义动作接口开发有个关键点execute方法必须返回SUCCESS。去年有个项目因为漏了返回值导致流程卡住三天找不到原因。标准动作开发模板如下public class CustomAction extends BaseBean implements Action { public String execute(RequestInfo request) { // 获取流程ID String workflowId request.getWorkflowid(); // 获取当前节点信息 String nodeId request.getNodenum(); // 业务逻辑处理... writeLog(流程workflowId在节点nodeId触发自定义动作); return Action.SUCCESS; // 必须返回SUCCESS } }2.2 数据集成方案选型与外部系统集成时我推荐优先考虑RESTful接口。E9提供了完善的鉴权机制通过OAuth2.0实现安全对接。下面是一个创建流程的典型请求示例String url http://oa.example.com/api/workflow/create; HttpClient client HttpClients.createDefault(); HttpPost post new HttpPost(url); // 设置鉴权头 post.setHeader(Authorization, Bearer accessToken); // 构建JSON请求体 JSONObject params new JSONObject(); params.put(workflowId, 123); params.put(formData, formJson); StringEntity entity new StringEntity(params.toString()); post.setEntity(entity); // 发送请求 HttpResponse response client.execute(post);对于需要高性能的场景可以考虑直接操作数据库中间表。但要注意做好数据校验和事务控制避免脏数据。3. 高频问题解决方案3.1 单点登录实现方案第三方系统集成时免密登录是刚需。E9的token机制其实很完善但配置步骤容易出错。必须确保web.xml里配好了WeaverLoginFilter同时WeaverLoginClient.properties要加上调用方IP。正确的token获取流程应该是调用/ssologin/getToken接口获取临时令牌拼接跳转URL时要特别注意参数位置PC端和移动端的URL结构不同一个常见的错误是把token放在hash后面正确的PC端URL应该是http://oa.example.com/wui/index.html?ssoTokenXXX#/main而不是http://oa.example.com/wui/index.html#/main?ssoTokenXXX3.2 性能优化要点数据库操作是性能瓶颈的重灾区。记住几个原则禁止在循环里new RecordSet使用预编译SQL防止注入事务操作要用RecordSetTrans推荐这样写SQLRecordSet rs new RecordSet(); // 使用参数化查询 rs.executeQuery(select * from hrmresource where id? and status?, id, 1); // 事务操作示例 RecordSetTrans rst new RecordSetTrans(); try { rst.setAutoCommit(false); rst.executeUpdate(update workflow set status? where id?, 2, 100); rst.commit(); } catch(Exception e) { rst.rollback(); }日志记录要用BaseBean的writeLog方法千万别用System.out。曾经有个系统因为大量System.out导致性能下降50%。4. 高级功能开发指南4.1 自定义WebService开发发布WebService接口其实很简单但要注意services.xml的配置格式。我遇到过一个坑是namespace写错导致客户端无法调用。标准开发流程如下创建接口类public interface DataSyncService { String syncUserData(JSONObject userInfo); }实现接口public class DataSyncServiceImpl implements DataSyncService { public String syncUserData(JSONObject userInfo) { // 实现数据同步逻辑 return success; } }在services.xml中添加配置service nameDataSyncService/name namespacehttp://services.example.com/namespace serviceClasscom.example.DataSyncService/serviceClass implementationClasscom.example.DataSyncServiceImpl/implementationClass /service4.2 定时任务开发计划任务接口适合做数据同步、报表生成等定时操作。开发时要继承BaseCronJob注意异常处理要完善否则任务失败会默默跳过。典型任务开发模板public class DailyReportJob extends BaseCronJob { public void execute() { try { // 生成日报逻辑 generateReport(); } catch(Exception e) { writeLog(生成日报失败e.getMessage()); // 重要任务可以考虑重试机制 } } }后台配置时cron表达式要特别注意时区问题。建议先用在线工具验证表达式是否正确。