IBM Java Toolbox 是一套为 Java 程序提供访问 IBM i 系统资源的 Java 类库。你可以使用这些类来编写与 IBM i 系统资源相关的应用程序。Java Toolbox 通过调用运行在 IBM i 上的服务来访问 IBM i 系统资源。每一个 IBM i 上的服务都是运行在一个单独的作业上,每一个服务作业通过 Socket 连接来发送和接受数据流。
IBM i 上有六种打印对象:假脱机文件、输出队列、打印机、打印机文件、写程序作业和高级功能打印资源。PrintObject 是 Java Toolbox 中打印对象的基类。这个类包含了所有访问 IBM i 打印对象的方法和属性。
本文将重点介绍打印机 Printer 和假脱机文件 SpooledFile 对象的相关属性和操作函数。其他四种打印对象的属性和操作与之相似,本文不做介绍。
该抽象类定义了打印对象的主要属性,包括字体属性(如 ATTR_FONT_CHANGES、ATTR_FONTID 等),打印格式属性(如 ATTR_FORMFEED 、ATTR_FORMTYPE 等)和页面属性(如 ATTR_PAGE_AT_A_TIME、ATTR_PAGELEN 等)。它有六个子类,分别是: AFPResource、OutputQueue、Printer、PrinterFile、SpooledFile、WriterJob。详细的参数可以参考 Java Toolbox 的 API 文档。Java Toolbox 是一个开源项目,在 sourceforge 上可以获得其源代码。
主要方法介绍 :
XXX getXXXAttribute(int attributeID)
返回一个由 attributeID 指定的某种类型的对象属性 , 主要的类型有 :String, Integer, Float
AS400 getSystem()
返回该对象所在的服务器 AS400 对象
void setSystem(AS400 system)
设置该对象所在的服务器 AS400 对象
void update()
通过到服务器检索对象的最新属性值来更新这个对象
该接口定义了对 PrintObject 类完整实现的函数。该接口有两个抽象类:PrintObjectImplRemote 和 PrintObjectImplProxy。PrintObjectImplRemote 是客户端直接访问 IBM i 服务器的实现方式,PrintObjectImplProxy 是客户端通过代理访问 IBM i 服务器的实现方式。本文主要介绍客户端直接访问服务器的实现方式。
有六个子类继承了抽象类 PrintObjectImplRemote,他们各自针对不同的打印对象实现了接口 PrintObjectImpl 中的函数。这六个子类分别是 : AFPResourceImplRemote、OutputQueueImplRemote、PrinterImplRemote、PrinterFileImplRemote、SpooledFileImplRemote、 WriterJobImplRemote。
PrintObject 中的 getXXXAttribute 方法运行时会调用到实现接口 PrintObjectImpl 的类中的 getXXXAttribute 方法。实际获得数据的操作都在 PrintObjectImpl 的方法中实现。
该抽象类定义了打印对象列表的主要操作。它有六个针对不同打印对象列表的子类,分别是:AFPResourceList、OutputQueueList、PrinterFileList、PrinterList、SpooledFileList、WriterJobList。
主要方法介绍 :
void openAsynchronously()
以异步的方式打开打印对象列表
void openSynchronously()
以同步的方式打开打印对象列表
void setAttributesToRetrieve(int[] attributes)
设置要访问的打印对象的属性组
void setImpl()
设置具体的实现类
void setSystem(AS400 system)
设置该对象所在的服务器 AS400 对象
该接口定义了对 PrintObjectList 类完整实现的函数。抽象类 PrintObjectListImplRemote 和 PrintObjectListImplProxy 继承了该接口。PrintObjectListImplRemote 有六个子类,分别是:AFPResourceListImplRemote、OutputQueueListImplRemote、PrinterFileListImplRemote、PrinterListImplRemote、SpooledFileListImplRemote、WriterJobListImplRemote。
PrintObjectList 中的 openAsynchronously(),openSynchronously(),setAttributesToRetrieve() 方法运行时会调用到实现接口 PrintObjectListImpl 的类中的同名方法。实际获得数据的操作都在 PrintObjectListImpl 的方法中实现。
以下用 4 个例子程序介绍如果访问 IBM i 上的打印机和假脱机文件资源。
在 IBM i 上可以通过 CL 命令 CRTDEVPRT 来添加一个打印机设备。在 IBM i Information Center 上可以找到该命令的详细说明。
下面的一个例子程序用来访问某台 IBM i 上的打印机列表。在控制台中,打印出这些打印机的名字。
清单 1. 获得 IBM i 上的打印机列表
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.Printer;
import com.ibm.as400.access.PrinterList;
public class PrintListExample {
private AS400 system;
public PrintListExample(AS400 system) {
this.system = system;
}
public void listPrinter() {
try {
String printerName;
if (system == null) {
system = new AS400();
}
System.out.println(" Receiving all printers synchronously: ");
PrinterList printerList = new PrinterList(system);
// 设置过滤条件:打印机名字 , *ALL 代表所有打印机
printerList.setPrinterFilter("*ALL");
// 以同步的方式打开打印机列表,这个方法直到列表完成才会返回
printerList.openSynchronously();
// 通过 enumeration 遍历获得的打印机列表
Enumeration enumeration = printerList.getObjects();
while (enumeration.hasMoreElements()) {
Printer printer = (Printer) enumeration.nextElement();
if (printer != null) {
// 获得打印机名字
printerName = printer.getStringAttribute(Printer.ATTR_PRINTER);
System.out.println(" printer name = " + printerName);
}
}
// 关闭列表
printerList.close();
} catch (Exception e) {
// 处理异常
e.printStackTrace();
}
}
public static void main(String args[]) {
PrintListExample list
= new PrintListExample(new AS400("sys","user","password"));
list.listPrinter();
System.exit(0);
}
}
|
在该程序中,我们使用 PrinterList 的父类 PrintObjectList 的方法 openSynchronously() 以同步的方式打开打印机列表,然后可以迭代的获得每个打印机 Printer 对象。PrintObjectList 类中除了 openSynchronously() 方法之外,还有 openAsynchronously() 方法。该方法以异步的方式获得打印机列表,该方法启动一个新的线程去调用同步方法 openSynchronously()。调用异步方法的时候,调用者可以通过注册监听器 ( 调用方法 addPrintObjectListListener),也可以直接调用 PrintObjectList 类中的方法 isCompleted()、waitForItem() 或者 waitForListToComplete() 去获得列表的打开状态。
注意,PrintObjectList 中的 openSynchronously() 最终是调用 PrintObjectListImpl 接口的某个实现子类中的 openSynchronously() 方法。在该例子中,最后会调到 PrinterListImplRemote 的 openSynchronously() 方法。
下面的一个例子程序用来访问 IBM i 上的指定名字的打印机的属性值。在控制台中,打印出这些打印机的属性值。
清单 2. 查看 IBM i 上打印机的属性
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.PrintObject;
import com.ibm.as400.access.Printer;
import com.ibm.as400.access.PrinterList;
public class PrintAttributeExample {
private AS400 system;
public PrintAttributeExample(AS400 system) {
this.system = system;
}
public void retrieveAttr() {
try {
if (system == null) {
system = new AS400();
}
System.out.println(" Receiving the printer synchronously: ");
PrinterList printerList = new PrinterList(system);
// 设置过滤条件:打印机名字
printerList.setPrinterFilter("test");
// 属性组,可以按你的需求访问各种属性
int[] attrArray =
{
PrintObject.ATTR_PRINTER,
PrintObject.ATTR_OVERALLSTS,
PrintObject.ATTR_DEVTYPE,
PrintObject.ATTR_DESCRIPTION,
};
// 设置要访问的属性组
printerList.setAttributesToRetrieve(attrArray);
// 以同步的方式打开打印机列表,这个方法直到列表完成才会返回 .
printerList.openSynchronously();
int size = printerList.size();
if (size >= 1) { // 有该名字的打印机
Printer printer = (Printer) printerList.getObject(0);
// 打印机名字
String name
= printer.getSingleStringAttribute(PrintObject.ATTR_PRINTER);
System.out.println("the printer name is:" + name);
// 打印机状态
Integer status
= printer.getIntegerAttribute(PrintObject.ATTR_OVERALLSTS);
System.out.println("the printer status is:" + status);
// 打印机类型
String type
= printer.getSingleStringAttribute(PrintObject.ATTR_DEVTYPE);
System.out.println("the printer type is:" + type);
// 打印机描述
String ds
= printer.getSingleStringAttribute(PrintObject.ATTR_DESCRIPTION);
System.out.println("the printer description is:" + ds);
} else { // 没有该名字的打印机
System.out.println("There is no printer matched with the name");
}
// 关闭列表
printerList.close();
} catch (Exception e) {
// 处理异常
e.printStackTrace();
}
}
public static void main(String args[]) {
PrintAttributeExample printer =
new PrintAttributeExample(new AS400("sys","user","password"));
printer.retrieveAttr();
System.exit(0);
}
}
|
在该程序中,我们使用 PrinterList 的父类 PrintObjectList 的方法 openSynchronously() 以同步的方式打开打印机列表,通过调用方法 setPrinterFilter("test") 设置了过滤条件,所以将获得名字为 test 的打印机。方法 setAttributesToRetrieve 设置了要访问的打印机属性,这些属性在接口 PrintObject 中都有定义。最后,调用 getXXXAttribute 方法来访问某种数据类型的属性值。
在 IBM i 上可以通过 CL 命令 WRKSPLF 来显示假脱机文件列表。在 IBM i Information Center 上可以找到该命令的详细说明。
下面的一个例子程序用来访问某台 IBM i 上的假脱机文件列表。在控制台中,打印出这些假脱机文件的名字、编号。
清单 3. 获得 IBM i 上的假脱机文件列表
import java.util.Enumeration;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.SpooledFile;
import com.ibm.as400.access.SpooledFileList;
public class SpooledFileListExample {
private AS400 system;
public SpooledFileListExample(AS400 system) {
this.system = system;
}
public void listSpooledFile() {
try {
if (system == null) {
system = new AS400();
}
System.out.println(" Receiving spooled file synchronously: ");
SpooledFileList spooledFileList = new SpooledFileList(system);
// 设置过滤条件:用户名字
spooledFileList.setUserFilter("ddsu");
// 设置开始和结束时间
spooledFileList.setStartDateFilter("1111109");
spooledFileList.setEndDateFilter("1111111");
// 以同步的方式打开假脱机文件列表,这个方法直到列表完成才会返回
spooledFileList.openSynchronously();
// 通过 enumeration 遍历获得的假脱机文件列表
Enumeration enumeration = spooledFileList.getObjects();
while (enumeration.hasMoreElements()) {
SpooledFile file = (SpooledFile) enumeration.nextElement();
if (file != null) {
// 获得假脱机文件名字
String name = file.getStringAttribute(SpooledFile.ATTR_SPOOLFILE);
System.out.println(" spooled file name = " + name);
// 编号
Integer no = file.getIntegerAttribute(SpooledFile.ATTR_SPLFNUM);
System.out.println(" spooled file number = " + no);
}
}
// 关闭列表
spooledFileList.close();
} catch (Exception e) {
// 处理异常
e.printStackTrace();
}
}
public static void main(String args[]) {
SpooledFileListExample list =
new SpooledFileListExample(new AS400("sys","user","password"));
list.listSpooledFile();
System.exit(0);
}
}
|
在该程序中,通过 setXXXFilter() 方法设置了过滤条件:假脱机文件的用户为 ddsu、创建时间在 2011-11-9 和 2011-11-11 之间,然后调用 openSynchronously() 方法列出满足这两个条件的假脱机文件。转换 IBM i 上的假脱机文件为 PDF 文件
下面的一个例子程序用来说明如何转换一个假脱机文件为 PDF 文件。
清单 4. 转换一个假脱机文件为 PDF 文件
import java.io.FileOutputStream;
import java.io.IOException;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.PrintObject;
import com.ibm.as400.access.PrintObjectTransformedInputStream;
import com.ibm.as400.access.PrintParameterList;
import com.ibm.as400.access.SpooledFile;
public class SpooledFileToPDFExample {
private AS400 system;
public SpooledFileToPDFExample(AS400 system) {
this.system = system;
}
public void convertSpooledFileToPDF(String splfname,
int splfnum, String jobName, String jobUser,String jobNumber) {
if (system == null) {
system = new AS400();
}
// 生成的 PDF 文件名称
String fileName = "D:\\test.pdf";
FileOutputStream fileoutputstream = null;
try {
// 构造假脱机文件实例
SpooledFile splf = new SpooledFile(system, splfname,
splfnum,jobName, jobUser, jobNumber);
fileoutputstream = new FileOutputStream(fileName);
PrintParameterList plist = new PrintParameterList();
// 设置转换格式 QCTXPDF.WSCST,将把假脱机文件转换为 PDF 格式
plist.setParameter(
PrintObject.ATTR_WORKSTATION_CUST_OBJECT, "/QSYS.LIB/QCTXPDF.WSCST");
plist.setParameter(PrintObject.ATTR_MFGTYPE, "*WSCST");
PrintObjectTransformedInputStream pdfInStream =
splf.getTransformedInputStream(plist);
if (pdfInStream != null) {
byte[] buffer = new byte[64 * 1024];
int bytesRead = 0;
while ((bytesRead = pdfInStream.read(buffer)) != -1) {
fileoutputstream.write(buffer, 0, bytesRead);
}
fileoutputstream.close();
}
// 关闭流
pdfInStream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileoutputstream != null) {
try {
fileoutputstream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String args[]) {
SpooledFileToPDFExample pdf =
new SpooledFileToPDFExample(new AS400("sys","user","password"));
pdf.convertSpooledFileToPDF("Qsysprt",1,"Qpadev0004","ddsu","005264");
System.exit(0);
}
}
|
在该程序中,通过设置转换格式 QCTXPDF.WSCST,调用方法 getTransformedInputStream() 把原始的假脱机文件内容转换为 PDF 格式,并且在客户端生成该 PDF 文件。需要注意的是,转换 PDF 的服务需要在 IBM i 上安装产品 5770TS1。
这篇文章介绍了 Java Toolbox 中访问 IBM i 的打印机资源的主要接口和类以及相关的操作。然后结合两个实际的例子程序来说明如何使用相关的类来访问 IBM i 上的打印机和假脱机文件。打印机和假脱机文件对象只是 IBM i 上打印资源六种类型中的两种,其他的四种类型的打印机资源可以通过类似方式来访问。他们具有统一的接口。
学习
-
IBM Toolbox for Java and JTOpen : 介绍 Java Toolbox。
-
Java Toolbox on sourceforge
-
IBM i Information Center: 更多 IBM i 的信息。
-
IBM developerWorks 中国 IBM i 专区 专区:提供给 IBM i 用户和开发者的专业技术资源。
获得产品和技术
- 最受欢迎的 WebSphere 试用软件下载:下载关键 WebSphere 产品的免费试用版。
- IBM developerWorks 软件下载资源中心:IBM deveperWorks 最新的软件下载。
- IBM developerWorks 工具包:下载关键 WebSphere 最新的产品工具包。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
- 加入 IBM 软件下载与技术交流群组,参与在线交流。