添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

To return expected results, you can:

  • Reduce the number of search terms. Each term you use focuses the search further.
  • Check your spelling. A single misspelled or incorrectly typed term can change your result.
  • Try substituting synonyms for your original terms. For example, instead of searching for "java classes", try "java training"
  • Did you search for an IBM acquired or sold product ? If so, follow the appropriate link below to find the content you need.
  • IBM Java Toolbox for i 数据转换类

    从面向对象的角度, IBM Java Toolbox for i 提供了一个 AS400DataType 接口,用于描述 IBM i 数据类型与 Java 数据类型之间的具体转换逻辑与规则。从 AS400DataType 接口对应的实现类,可大致可分为:

    • 数值
    • 文本
    • 日期
    • 复合类型(数字与文本)

    1 对应的是与数字相关的 AS400DataType 实现类。

    1. AS400DataType 相关的实现类

    • 数字类型
    • 类说明
    • AS400Bin2
    • Java Short 对象与 IBM i 有符号双字节短整数的转换。
    • AS400Bin4
    • Java Integer 对象与 IBM i 有符号四字节整数的转换。
    • AS400ByteArray
    • IBM i 字节数组之间的转换。
    • AS400Float4
    • Java Float 对象与 IBM i 有符号四字节浮点数的转换。
    • AS400Float8
    • Java Double 对象与 IBM i 有符号八字节浮点数的转换。
    • AS400PackedDecimal
    • Java BigDecimal 对象与 IBM i 压缩十进制( PACKED DECIMAL )数的转换。
    • AS400UnsignedBin2
    • Java Integer 对象与 IBM i 无符号双字节整数的转换。
    • AS400UnsignedBin4
    • Java Long 对象与 IBM i 无符号四字节整数的转换。
    • AS400ZonedDecimal
    • Java BigDecimal 对象与 IBM i 区位十进制( ZONED DECIMAL )数的转换。

    对于 IBM i RPG 程序而言, PACKED DECIMAL ZONED DECIMAL 是两种常见的数值类型,虽然两者功能一样,都可以存放数值型数据,但它们所占存储空间是不一样的。 ZONED DECIMAL 用一个字节存放一个数字,而 PACKED DECIMAL 用一个字节存放两个数字。因此, PACKED DECIMAL 节约了存储空间。基于存储空间的考虑, IBM i RPG 编译器将 ZONED DECIMAL 数据自动转换为 PACKED DECIMAL 类型。因此,推荐使用 PACKED DECIMAL 类型,可节省存储控件,提高编译效率。另外, PACKED DECIMAL 的长度定义为奇数长度会更节省存储空间。

    数值转换类

    作为例子,清单 1 描述的是如何使用 AS400Bin4 转换类,将 IBM i 格式的数值转换成 Java 整形。这里需要强调的是,所有的 IBM i 的数据我们都用字节数组来表示。

    清单 1. IBM i 数值类型转换 Java int 类型

    byte[] data = new byte[100];

    // Number Converter

    AS400Bin4 bin4Converter = new AS400Bin4();

    Integer intObject = (Integer) bin4Converter.toObject(data,0);

    int i = intObject.intValue();

    清单 2 可以看作是清单 1 的逆过程,描述的是 Java 整形转换成 IBM i 格式的数值。

    清单 2. Java int 类型转换 IBM i 数值类型

    Integer intObject = new Integer(22);

    // Number Converter

    AS400Bin4 bin4Converter = new AS400Bin4();

    byte[] data = bin4Converter.toBytes(intObject);

    int length = bin4Converter.getByteLength();

    文本转换类

    说完了数值类型,现在来看一下文本类型。从 AS400DataType 接口对应的实现类的角度, AS400Text 实现了 IBM i 格式与 Java 字符串的类型转换。作为示例,清单 3 描述了字符串从 EBCDIC Unicode 的转换。

    清单 3. IBM i 字符串转换成 Java 字符串

    byte[] data = new byte[100];

    // Text Converter

    AS400Text textConverter = new AS400Text(textLength, ccsid, system);

    String javaText = (String) textConverter.toObject(data);

    这里,我们结合前面图 2 给出的示例,验证 EBCDIC 编码的正确性。前面提到,字符序列“我来自 IBM 对应 EBCDIC 的编码为:

    57 D1 50 B3 5C B4 C9 C2 D4

    根据我们前面的介绍, CCSID 935 表示的是简体中文字符集,双字节,因此分视为两个字符表,低字节对应 CCSID 836 的字符表,高字节对应 CCSID 837 的字符表。

    因此,我们构造两个字节数组 data1 data2 ,如清单 4 所示。指定对应的 CCSID 值分别为 837 ,与 836 ,即采用 CCSID 935 的简体中文字符集。然后,我们使用 AS400Text 类将其转换成 Unicode 编码,并显示。最后的结果是: It should print true? true

    清单 4. EBCDIC 中文字符编码应用举例

    //CCSID=837 编码汉字部分

    byte[] data1 = {(byte)0x57,(byte)0xD1,(byte)0x50,(byte)0xB3,(byte)0x5C,(byte)0x74};

    //CCSID=836 编码非汉字部分

    byte[] data2 = {(byte)0xC9,(byte)0xC2,(byte)0xD4};

    String ccsid1 = "837";

    String ccsid2 = "836";

    AS400Text textConverter1 = new AS400Text(6, ccsid1);

    AS400Text textConverter2 = new AS400Text(3, ccsid2);

    String str1 = (String) textConverter1.toObject(data1);

    String str2 = (String) textConverter2.toObject(data2);

    System.out.println("It should print true? " + " 我来自 IBM".equals(str1+str2));

    作为另一个特殊的文本类型转换类, AS400BidiTransform 描述了双向语言(如阿拉伯语)的 IBM i 文本格式与 Java Unicode 字符串的转换,如示例清单 5 所示。

    清单 5. IBM i 双向语言文本与 Java Unicode 字符串的转换

    // Java data to IBM i layout:

    AS400BidiTransform abt = new AS400BidiTransform(424);

    String dst = abt.toAS400Layout("some bidi string");

    // Specifying a new CCSID for an existing AS400BidiTransform object:

    abt.setAS400Ccsid(62234); // 420 RTL //

    String dst = abt.toAS400Layout("some bidi string");

    // Specifying a non-default string type for a given CCSID:

    abt.setAS400StringType(BidiStringType.ST4); // Vis LTR //

    String dst = abt.toAS400Layout("some bidi string");

    // Specifying a non-default string type for Java data:

    abt.setJavaStringType(BidiStringType.ST11); // Imp Context LTR //

    String dst = abt.toAS400Layout("some bidi string");

    // How to transform IBM i data to Java layout:

    abt.setJavaStringType(BidiStringType.ST6); // Imp RTL //

    String dst = abt.toJavaLayout("some bidi string");

    日期转换类

    说完了数值类型与文本类型,接下来说一下日期类型。从 AS400DataType 接口对应的实现类的角度,抽象类 AS400AbstractTime 实现了 IBM i 格式与 Java 字符串的类型转换。按照日期,时间,时间戳等进一步细分, AS400AbstractTime 又分为三个子类 AS400Date AS400Time AS400Timestamp

    我们知道,在 Java 中,用于表示时间的类是 Date ,分别对应 java.sql .java.util AS400Date 实现的是 IBM i 时间格式与 java.sql.Date 类型的转换。相应地, AS400Time AS400Timestamp 均按照类似的逻辑,与 java.sql Time Timestamp 分别映射。关于 AS400Date AS400Time AS400Timestamp 的用法,分别如清单 6 ,清单 7 ,清单 8 所示:

    清单 6. AS400Date 的使用

    import java.text.SimpleDateFormat;

    // value to be generated by AS400Date

    java.sql.Date date1;

    // Set the formatter's time zone to GMT.

    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

    formatter.setTimeZone(as400.getTimeZone());

    ...

    System.out.println("Date value: " + formatter.format(date1));

    清单 7. AS400Time 的使用

    import java.text.SimpleDateFormat;

    // value to be generated by AS400Time

    java.sql.Time time1;

    // Set the formatter's time zone to the server timezone.

    SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); formatter.setTimeZone(as400.getTimeZone());

    ...

    System.out.println("Time value: " + formatter.format(time1));

    清单 8. AS400Timestamp 的使用

    import java.text.SimpleDateFormat;

    // value to be generated by AS400Timestamp

    java.sql.Timestamp timestamp1;

    // Set the formatter's time zone to the servers time zone

    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    formatter.setTimeZone(as400.getTimeZone());

    ...

    System.out.println("Timestamp value: " + formatter.format(timestamp1));

    数组及结构转换类

    谈完了数值类型,文本字符类型(包括对双向语言的支持),时间类型,最后我们来看一下符合类型。从 AS400DataType 接口对应的实现类的角度,对于符合类型的转换类支持分为两种:

    AS400Array – 便于 Java 程序员方便操作数组类型。

    AS400Structure - 便于 Java 程序员方便操作结构体类型。

    AS400Array 的概念比较好理解,作为示例,清单 9 描述了 AS400Structure 的用法。

    清单 9. AS400Structure 的使用

    AS400DataType[] myStruct =

    {

    new AS400Bin4(),

    new AS400ByteArray(4),

    new AS400Float8(),

    new AS400Text(40)

    };

    // Create a conversion object using the structure.

    AS400Structure myConverter = new AS400Structure(myStruct);

    // Create the Java object that holds the data to send to the server.

    Object[] myData =

    {

    new Integer(88), // the four-byte number

    new byte[0], // the pad (let the conversion object 0 pad)

    new Double(23.45), // the eight-byte floating point number

    "This is my structure" // the character string

    };

    // Convert from Java object to byte array.

    byte[] myAS400Data = myConverter.toBytes(myData);

    Object[] myRoundTripData = (Object[])myConverter.toObject(myAS400Data,0);

    Double doubleObject = (Double) myRoundTripData[2];

    double d = doubleObject.doubleValue();

    至此,我们已介绍完如何实现基于数值、文本、日期、数组及结构类型的数据转换。

    总结

    总之, EBCDIC IBM 特有的一种字符编码。按照 CCSID 的不同,对应不同的字符编码表。对于从事 IBM i 平台相关工作的程序开发人员而言,推荐使用 IBM Java Toolbox for i ,不用考虑 IBM i EBCDIC Java Unicode 之间的转换规则,因为 IBM Java Toolbox for i 已经内置转码引擎,并提供两种不同粒度的代码转换类。这样,程序开发人员就可以把更多的时间与精力投入到程序的业务逻辑,提高开发效率,节省了成本。

    参考资源

    参看文章 “Toolbox for Java JTOpen” ,了解 IBM Java Toolbox for i 的概要信息。

    作者:皮光明