2. Windchill API基础
Windchill 的二次开发能力几乎全部建立在 Java API 之上。理解 API 的分类方式、包与类的组织逻辑,以及远程方法调用(RMI)的底层机制,是写出第一个可运行接口程序的前提。本节从“是什么”讲到“怎么跑通”,并给出一个可直接参考的示例。
一、Windchill API 的分类
按调用位置与用途,Windchill API 大致可分为四类:
- 业务服务 API(Business Services):面向业务对象的高层接口,如
wt.part.WTPart、wt.doc.WTDocument、wt.change2.WTChangeOrder2,用于创建、查询、修订、检入检出等操作。 - 持久化与查询 API:如
wt.fc.PersistenceHelper、wt.fc.QueryResult、wt.query.QuerySpec,负责对象存取与条件检索。 - 服务端扩展 API:如
wt.services.StandardService、wt.method.RemoteAccess,用于编写自定义服务并暴露给远程调用。 - 客户端与集成 API:如
wt.client包下的远程代理、wt.util.WTProperties读取配置,用于外部系统对接。
分类的意义在于:写业务逻辑优先用业务服务 API,做数据检索用查询 API,而要让外部系统调用,则必须理解服务端扩展与远程调用机制。
二、常用包与类
Windchill 的包名以 wt. 开头,按功能域划分。下表列出开发中最常打交道的包与代表类:
| 包名 | 代表类 | 典型用途 |
|---|---|---|
| wt.fc | PersistenceHelper、WTCollection、QueryResult | 对象持久化、集合与查询结果处理 |
| wt.part | WTPart、WTPartMaster | 零部件创建与版本管理 |
| wt.doc | WTDocument、WTDocumentMaster | 文档对象操作 |
| wt.query | QuerySpec、SearchCondition、ColumnExpression | 构造条件查询 |
| wt.session | SessionHelper、WTPrincipal | 会话与用户上下文 |
| wt.method | RemoteMethodServer、RemoteAccess | 远程方法调用入口 |
| wt.util | WTProperties、WTException | 配置读取与异常处理 |
其中 PersistenceHelper.manager 与 SessionHelper.manager 是几乎所有接口程序都会用到的两个“管理器”入口,前者负责持久化,后者负责会话上下文。
三、远程方法调用机制
Windchill 采用 RMI(Remote Method Invocation)实现客户端与服务端之间的方法调用。其核心是:客户端持有服务端对象的远程代理(stub),调用方法时参数被序列化,经 RMI 传输到服务端,由服务端执行后把结果序列化返回。整个过程对开发者基本透明,但有几个关键约束:
- 被远程调用的类必须实现
wt.method.RemoteAccess接口,或继承wt.services.StandardService。 - 方法参数与返回值必须可序列化(实现
java.io.Serializable)。 - 服务端需通过
RemoteMethodServer.getDefault()获取实例,再用invoke()调用。 - 调用前必须建立会话,通常用
SessionHelper.manager.setAdministrator()或指定用户登录。
下图展示了从客户端到服务端的完整调用链与关键对象:
四、开发环境准备
在写第一个接口程序前,需要完成以下准备:
- JDK 版本匹配:Windchill 11.x/12.x 通常要求 JDK 8 或 JDK 11,需与服务器端一致,避免序列化版本冲突。
- 类路径配置:将
Windchill/codebase下的wt.jar、Wncustom.jar等加入 IDE 的 Build Path。 - 连接配置:在
wt.properties或wt.rmi.client.properties中配置 RMI 主机、端口(默认wt.rmi.port=1099)及服务名。 - 登录凭据:准备 Windchill 管理员或具备相应权限的用户账号,用于
SessionHelper登录。 - 编译与部署:自定义类编译后放入
codebase或通过wt.load工具加载,确保服务端可加载到该类。
五、第一个接口程序示例
下面是一个查询指定编号零部件的远程接口示例。它演示了登录、构造查询条件、执行查询并输出结果的完整过程。示例中的零件编号 P-1001 为教学假设值,实际运行时请替换为系统中真实存在的编号。
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.part.WTPart;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.session.SessionHelper;
import wt.method.RemoteMethodServer;
public class FirstPartQuery {
public static void main(String[] args) throws Exception {
// 1. 建立会话(示例使用管理员)
SessionHelper.manager.setAdministrator();
// 2. 获取远程方法服务器
RemoteMethodServer rms = RemoteMethodServer.getDefault();
// 3. 构造查询条件:按零件编号精确匹配
QuerySpec qs = new QuerySpec(WTPart.class);
qs.appendWhere(new SearchCondition(
WTPart.class, "number", SearchCondition.EQUAL, "P-1001"), new int[]{0});
// 4. 执行查询
QueryResult qr = PersistenceHelper.manager.find(qs);
// 5. 遍历结果
while (qr.hasMoreElements()) {
WTPart part = (WTPart) qr.nextElement();
System.out.println("找到零件: " + part.getNumber()
+ " | 名称: " + part.getName()
+ " | 版本: " + part.getVersionIdentifier().getValue());
}
}
}
运行后若控制台输出类似 找到零件: P-1001 | 名称: 示例支架 | 版本: A,说明 RMI 通道、会话与查询 API 均已正常工作。若抛出 WTException,优先检查:类路径是否包含 wt.jar、RMI 端口是否可达、登录用户是否有该零件的读取权限。
Serializable 并确保客户端与服务端使用同一版本类。掌握以上内容后,你已经具备编写并运行一个基础 Windchill 接口程序的能力。后续更复杂的创建、修订、工作流触发等操作,都建立在这套“会话 + 远程服务 + 持久化”的调用模型之上。