JiBX 1.2, Phần 1: Từ mã Java thành lược đồ XML

Cải thiện chất lượng lược đồ bằng phép biến đổi tùy chỉnh các mô hình dữ liệu Java thành tài liệu XML và từ tài liệu XML

Các định nghĩa lược đồ XML là cơ sở cho nhiều kiểu trao đổi dữ liệu, bao gồm hầu hết các dạng dịch vụ web. Nhưng lược đồ XML là một tiêu chuẩn phức tạp và hầu hết các công cụ để tạo và sửa đổi các định nghĩa lược đồ không đủ mạnh mẽ hay dễ sử dụng như các công cụ để làm việc với mã Java™. Các đặc tính mới của JiBX 1.2 mà bạn sẽ tìm hiểu về nó trong hướng dẫn này — Phần 1 của một loạt bài viết có hai phần — cho phép bạn bắt đầu từ mã Java và dễ dàng tạo ra các định nghĩa lược đồ có chất lượng khớp với các cấu trúc dữ liệu của bạn. Sau đó bạn có thể sử dụng trực tiếp các lược đồ này, dù bạn có sử dụng liên kết dữ liệu JiBX hay không.

Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc.

Dennis Sosnoski là một nhà tư vấn và nhà trợ giúp đào tạo chuyên về các dịch vụ Web và SOA dựa trên-Java. Kinh nghiệm phát triển phần mềm chuyên nghiệp của ông trải suốt hơn 30 năm qua, với một thập kỉ cuối tập trung vào các công nghệ XML và Java phía máy chủ. Dennis là nhà phát triển hàng đầu về dụng cụ liên kết dữ liệu XML JiBX mã nguồn mở, cũng là một người có duyên nợ với khung công tác của các dịch vụ Web Apache Axis2. Ông cũng là một trong những thành viên của nhóm chuyên gia đặc tả kỹ thuật của Jax-WS 2.0 và JAXB 2.0. Xem trang web của ông để có thông tin về các dịch vụ đào tạo và tư vấn của ông.



20 05 2009

Trước khi bạn bắt đầu

Về hướng dẫn này

JiBX là một công cụ để liên kết dữ liệu XML với các đối tượng Java. Liên kết dữ liệu JiBX đã được biết đến từ lâu như là cách tiếp cận nhanh nhất và linh hoạt nhất để liên kết mã Java tới XML. Nhưng sự phức tạp của các định nghĩa liên kết JiBX và sự hỗ trợ còn hạn chế của nó với các định nghĩa lược đồ XML đang được sử dụng ngày càng rộng rãi hơn đã làm cho những người dùng thất vọng nhiều lần. May mắn thay, phiên bản 1.2 của JiBX đã tiến một bước dài theo hướng loại bỏ những vấn đề này. Trong hướng dẫn này, bạn sẽ tìm hiểu về việc sử dụng các đặc tính mới của JiBX 1.2 để tạo ra các định nghĩa lược đồ XML một cách dễ dàng từ mã Java hiện có và để đọc và viết các tài liệu khớp với các định nghĩa lược đồ đã tạo ra — hoàn toàn không cần phải đi vào các chi tiết của các định nghĩa liên kết của JiBX. Phần 2 trình bày nửa còn lại của vấn đề: bắt đầu từ các định nghĩa lược đồ XML và tạo mã Java.

Mục tiêu

Hướng dẫn này chỉ dẫn cho bạn về quá trình sử dụng JiBX để tạo ra các định nghĩa lược đồ XML từ mã Java. Đầu tiên, bạn sẽ thấy làm thế nào để bắt đầu với một mô hình dữ liệu Java đơn giản và tạo ra một lược đồ mặc định khớp với mô hình đó. Trên cơ sở đó, bạn sẽ tìm hiểu cách làm thế nào để bạn có thể dễ dàng áp dụng một loạt các tuỳ chỉnh để kiểm soát các giá trị thực tế đã sử dụng trong các lớp Java của bạn và cách làm thế nào để truy cập chúng, cho dù chúng là cần phải có (required) hay tùy chọn (optional); để kiểm soát các tên và các không gian tên (namespaces) được sử dụng trong XML và thậm chí để kiểm soát cấu trúc của các định nghĩa lược đồ đã tạo ra. Đồng thời, bạn sẽ thấy JiBX tăng thêm giá trị cho các lược đồ bạn đã tạo ra như thế nào khi sử dụng những công sức đầu tư của bạn vào Javadocs để làm tài liệu về định nghĩa lược đồ một cách tự động. Sau khi đọc hướng dẫn này và thực hiện các ví dụ được cung cấp, bạn sẽ có khả năng sử dụng JiBX để tạo ra các định nghĩa lược đồ XML có chất lượng từ các lớp cấu trúc dữ liệu Java riêng của bạn.

Các điều kiện cần có trước

Để hiểu được hướng dẫn này, bạn ít nhất nên có các kiến thức cơ bản về cả mã Java và XML. Bạn không cần phải hiểu biết chi tiết về các định nghĩa lược đồ XML nhưng sự quen thuộc với các lược đồ sẽ giúp bạn hiểu các ví dụ tốt hơn.

Các yêu cầu hệ thống

Để chạy các ví dụ này, bạn cần phải cài đặt:

Các hướng dẫn tải về và cài đặt JiBX có trong hướng dẫn này.


Bắt đầu

Trong phần này, bạn sẽ có được cái nhìn tổng quan về JiBX và bạn sẽ cài đặt JiBX và mã lệnh mẫu của hướng dẫn này.

Giới thiệu JiBX

JiBX là một trong nhiều công cụ dùng để chuyển đổi giữa các cấu trúc dữ liệu Java và các tài liệu XML (Tài nguyên). Cái làm nên sự khác biệt của JiBX so với những công cụ khác là các đặc tính linh hoạt và hiệu năng. Hiệu năng của JiBX luôn được đánh giá ở vị trí cao nhất trong lĩnh vực này, vượt quá hai lần hoặc hơn nữa so với hiệu năng của các công cụ phổ biến khác (như JAXB 2.0 chẳng hạn). JiBX cũng linh hoạt hơn hầu hết tất cả các công cụ Java-XML khác, khi sử dụng các định nghĩa liên kết để tách các cấu trúc Java khỏi biểu diễn XML sao cho từng cái có thể được thay đổi độc lập với cái kia.

Với bản phát hành 1.2, JiBX bổ sung thêm các đặc tính hỗ trợ các định nghĩa lược đồ XML. Bạn có thể sử dụng các công cụ kèm theo trong bản phát hành JiBX để tạo ra một định nghĩa lược đồ khớp với mã Java của bạn hoặc để tạo mã Java khớp với định nghĩa lược đồ của bạn. Dù bằng cách nào, bạn cũng nhận được một định nghĩa liên kết để cho phép bạn sử dụng JiBX để chuyển đổi giữa các mã Java và các tài liệu XML khớp với định nghĩa lược đồ. Trong hướng dẫn này, bạn sẽ thấy cách làm thế nào để áp dụng kiểu tạo mã đầu tiên: từ mã Java sinh ra định nghĩa lược đồ.

Cài đặt JiBX

Bạn cần phải cài đặt JiBX trước khi tiếp tục thực hiện hướng dẫn này. Hãy tải về bản ZIP phân phối mới nhất 1.2.x và giải nén nó vào một chỗ thuận tiện trên hệ thống của bạn. Xong việc, bạn sẽ nhận được một thư mục có tên là jibx, trong đó có chứa tất cả các tệp JiBX JAR, tài liệu hướng dẫn, các ví dụ và thậm chí cả mã nguồn.

Cài đặt mã nguồn các ví dụ của hướng dẫn này

Bây giờ hãy tải về các mã mẫu, của hướng dẫn này, cũng được cung cấp dưới dạng một tệp tin ZIP. Cách dễ nhất để cài đặt nó trên hệ thống của bạn là giải nén tệp tin ZIP vào thư mục gốc của bản phân phối JiBX của bạn (hoặc trên Windows®, sao chép thư mục dwcode1 từ bên trong tệp tin ZIP này vào thư mục gốc bản phân phối JiBX của bạn). Điều này sẽ tạo ra một thư mục con dwcode1 trong thư mục jibx, với các tệp tin ví dụ (bao gồm cả các tệp tin build.xml, custom1.xml và các tệp tin khác) bên trong thư mục con dwcode1 đó.

Mã mẫu bao gồm một tệp tin xây dựng Ant Apache để tự động hoá cho chạy các công cụ JiBX và xử lý các bước khác có trong các ví dụ. Nếu bạn cài đặt các mã mẫu trực tiếp vào thư mục cài đặt của JiBX, công cụ xây dựng (build) có thể truy cập các tệp JiBX JAR mà không cần thêm bất kỳ cấu hình nào. Nếu bạn cài đặt các mã mẫu ở nơi khác, bạn vẫn có thể sử dụng công cụ xây dựng Ant. Trong trường hợp này, bạn chỉ cần thiết lập một biến môi trường JIBX_HOME chỉ rõ đường dẫn đến bản cài đặt JiBX của bạn. Ngoài ra, một cách khác là bạn có thể chỉnh sửa các tệp tin build.xml-bên trong thư mục mã mẫu và bỏ dấu chú thích ở đầu các dòng phía trên cùng của tệp tin, nơi trực tiếp thiết lập các thuộc tính jibx-home.


Tạo ra liên kết mặc định và lược đồ từ mã Java

Cách sử dụng cho trường hợp không phải Java 5

Mã ví dụ của hướng dẫn này sử dụng các đặc tính về bảng kê (enum) và sưu tập có định kiểu của Java 5, nhưng bản thân JiBX hoàn toàn tương thích với các phiên bản Java cũ hơn. Môi trường chạy JiBX tiêu chuẩn làm việc được với các JVM phiên bản 1.3 và mới hơn và cũng có thể được xây dựng để tương thích với J2ME. Hầu hết các thành phần khác của JiBX bao gồm cả BindGen, có thể chạy được trên các bản JVM phiên bản 1.4.1 và mới hơn. Tài liệu BindGen trong bản tải về JiBX có một ví dụ chỉ rõ cách tùy chỉnh như thế nào để có thể cung cấp cho BindGen các thay thế tương đương của các sưu tập có định kiểu nếu bạn sử dụng mã Java cũ hơn phiên bản Java 5.

Thật dễ dàng để tạo ra một định nghĩa liên kết JiBX và định nghĩa lược đồ XML tương ứng từ mã Java. Bạn sẽ tìm hiểu cách làm thế nào trong phần này.

Giới thiệu về mã ví dụ Java

Như một ví dụ, tôi sẽ bắt đầu với mã Java cho một tập các lớp theo phong cách bean (các trường dữ liệu là riêng-private và các phương thức set và các phương thức get là chung-public) dùng để mô tả một đơn hàng từ một cửa hàng trực tuyến. Listing 1 hiển thị một phiên bản mã rút gọn, bỏ qua hầu hết các phương thức get/set. Toàn bộ mã mẫu hoàn chỉnh nằm trong thư mục src các mã mẫu.

Listing 1. Mã Java cơ sở
package org.jibx.starter;

/**
 * Order information.
 */
public class Order
{
    private long orderNumber;
    private Customer customer;

    /** Billing address information. */
    private Address billTo;
    private Shipping shipping;

    /** Shipping address information. If missing, the billing address is also used as the
     shipping address. */
    private Address shipTo;
    private List<Item> items;

    /** Date order was placed with server. */
    private Date orderDate;

    /** Date order was shipped. This will be <code>null</code> if the order has not
     yet shipped. */
    private Date shipDate;
    private Float total;

    public long getOrderNumber() {
        return orderNumber;
    }
    ...
}
/**
 * Customer information.
 */
public class Customer
{
    private long customerNumber;

    /** Personal name. */
    private String firstName;

    /** Family name. */
    private String lastName;

    /** Middle name(s), if any. */
    private List<String> middleNames;
    ...
}
/**
 * Address information.
 */
public class Address
{
    /** First line of street information (required). */
    private String street1;

    /** Second line of street information (optional). */
    private String street2;
    private String city;

    /** State abbreviation (required for the U.S. and Canada, optional otherwise). */
    private String state;

    /** Postal code (required for the U.S. and Canada, optional otherwise). */
    private String postCode;

    /** Country name (optional, U.S. assumed if not supplied). */
    private String country;
    ...
}
/**
 * Order line item information.
 */
public class Item
{
    /** Stock identifier. This is expected to be 12 characters in length, with two
     leading alpha characters followed by ten decimal digits. */
    private String id;

    /** Text description of item. */
    private String description;

    /** Number of units ordered. */
    private int quantity;

    /** Price per unit. */
    private float price;
    ...
}
/**
 * Supported shipment methods. The "INTERNATIONAL" shipment methods can only be used for
 * orders with shipping addresses outside the U.S., and one of these methods is required
 * in this case.
 */
public enum Shipping
{
    STANDARD_MAIL, PRIORITY_MAIL, INTERNATIONAL_MAIL, DOMESTIC_EXPRESS,
    INTERNATIONAL_EXPRESS
}

Tạo liên kết và lược đồ mặc định

Để tạo ra một liên kết JiBX và lược đồ XML từ một số lớp Java, đầu tiên bạn cần phải biên dịch các lớp, sau đó chạy công cụ org.jibx.binding.generator.BindGen có trong jibx-tools.jar từ bản phân phối JiBX. Bạn có thể chạy trực tiếp công cụ từ dòng lệnh hoặc gián tiếp thông qua một công cụ xây dựng như Ant.

Trong tệp tải về của hướng dẫn có chứa một kịch bản lệnh Ant build.xml với đích compile để biên dịch mã ví dụ và đích bindgen để chạy chương trình BindGen trên mã đã biên dịch.

Để thử làm việc này, mở một cửa sổ lệnh trong thư mục dwcode1 nơi cài đặt ví dụ đã tải về và gõ ant compile bindgen. Nếu Ant đã được cài đặt trên hệ thống và bạn đã cài đặt mã đã tải xuống theo đúng các chỉ dẫn, bạn sẽ thấy kết quả tương tự như được hiển thị trong Hình 1:

Hình 1. Sử dụng công cụ xây dựng Ant
Kết quả đầu ra của công cụ xây dựng Ant để tạo từ mã

Bạn cũng có thể chạy BindGen trực tiếp từ cửa số lệnh. Để làm được điều này, bạn cần đưa thêm vào biến môi trường Java classpath của bạn tên tệp tin jibx-tools.jar cùng với đường dẫn đến các tệp tin lớp đã biên dịch sẽ được sử dụng làm đầu vào cho BindGen. Nếu bạn muốn tạo bản sao đúp kết quả của đích Ant bindgen, đã cung cấp, bạn cũng cần phải thêm vào dòng lệnh cả tên thư mục gốc của các tệp mã nguồn của các lớp đó. Cuối cùng, bạn cần liệt kê (các) lớp gốc mà bạn muốn sử dụng cho việc sinh mã. Trên các hệ thống UNIX® và Linux®, dòng lệnh Java (chỉ là một dòng, ngay cả khi hiển thị màn hình có xuống dòng vì quá dài) để sao đúp đích Ant bindgen từ cửa sổ lệnh trong thư mục dwcode1 (giả thiết bạn đã làm theo đúng các chỉ dẫn cài đặt được khuyến cáo) là:

java -cp ../lib/jibx-tools.jar:bin org.jibx.binding.generator.BindGen 
   -s src org.jibx.starter.Order

Trên Windows, dòng lệnh (chỉ là một dòng, bất kể hiển thị ở đây như thế nào) là:

java -cp ..\lib\jibx-tools.jar;bin org.jibx.binding.generator.BindGen 
   -s src org.jibx.starter.Order

Có thể chuyển thêm nhiều tham số tùy chọn khác đến dòng lệnh cho chạy BindGen. Bạn sẽ xem xét các tùy chọn đó sau trong hướng dẫn này. Bây giờ, hãy nhìn vào lược đồ đã tạo ra.

Các tạo phẩm được tạo ra

Listing 2 cho thấy lược đồ kết quả đã tạo ra từ BindGen (tên là starter.xsd), được định dạng lại một chút cho phù hợp với độ rộng trang và bỏ bớt một số chi tiết. Thẻ bắt đầu của định nghĩa lược đồ khớp với mỗi lớp Java được hiển thị bằng chữ in đậm để nhấn mạnh cấu trúc.

Listing 2. Lược đồ được tạo ra
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://jibx.org/starter" elementFormDefault="qualified"
  targetNamespace="http://jibx.org/starter">
 <xs:complexType name="address">
  <xs:annotation>
   <xs:documentation>Address information.</xs:documentation>
  </xs:annotation>
  <xs:sequence>
   <xs:element type="xs:string" name="street1" minOccurs="0">
    <xs:annotation>
     <xs:documentation>First line of street information (required).</xs:documentation>
    </xs:annotation>
   </xs:element>
   ...
  </xs:sequence>
 </xs:complexType>
 <xs:element type="tns:order" name="order"/> <xs:complexType name="order">
  <xs:annotation>
   <xs:documentation>Order information.</xs:documentation>
  </xs:annotation>
  <xs:sequence>
   <xs:element name="customer" minOccurs="0">
    <xs:complexType>
     ...
    </xs:complexType>
   </xs:element>
   <xs:element type="tns:address" name="billTo" minOccurs="0">
    <xs:annotation>
     <xs:documentation>Billing address information.</xs:documentation>
    </xs:annotation>
   </xs:element>
   <xs:element name="shipping" minOccurs="0">
    <xs:simpleType>
     <xs:annotation>
      <xs:documentation>Supported shipment methods. The "INTERNATIONAL" shipment methods
        can only be used for orders with shipping addresses outside the U.S., and one of
        these methods is required in this case.</xs:documentation>
     </xs:annotation>
     <xs:restriction base="xs:string">
      <xs:enumeration value="STANDARD_MAIL"/>
      ...
     </xs:restriction>
    </xs:simpleType>
   </xs:element>
   <xs:element type="tns:address" name="shipTo" minOccurs="0">
    <xs:annotation>
     <xs:documentation>Shipping address information. If missing, the billing address is
       also used as the shipping address.</xs:documentation>
    </xs:annotation>
   </xs:element>
   <xs:element name="item" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
     <xs:sequence>
      <xs:element type="xs:string" name="id" minOccurs="0">
       <xs:annotation>
        <xs:documentation>Stock identifier. This is expected to be 12 characters in
          length, with two leading alpha characters followed by ten decimal
          digits.</xs:documentation>
       </xs:annotation>
      </xs:element>
      <xs:element type="xs:string" name="description" minOccurs="0">
       <xs:annotation>
        <xs:documentation>Text description of item.</xs:documentation>
       </xs:annotation>
      </xs:element>
     </xs:sequence>
     <xs:attribute type="xs:int" use="required" name="quantity">
      <xs:annotation>
       <xs:documentation>Number of units ordered.</xs:documentation>
      </xs:annotation>
     </xs:attribute>
     <xs:attribute type="xs:float" use="required" name="price">
      <xs:annotation>
       <xs:documentation>Price per unit.</xs:documentation>
      </xs:annotation>
     </xs:attribute>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
  <xs:attribute type="xs:long" use="required" name="orderNumber"/>
  <xs:attribute type="xs:date" name="orderDate">
   <xs:annotation>
    <xs:documentation>Date order was placed with server.</xs:documentation>
   </xs:annotation>
  </xs:attribute>
  <xs:attribute type="xs:date" name="shipDate">
   <xs:annotation>
    <xs:documentation>
     <![CDATA[Date order was shipped. This will be <code>null</code> if the order
       has not yet shipped.]]></xs:documentation>
   </xs:annotation>
  </xs:attribute>
 </xs:complexType>
</xs:schema>

Theo mặc định, BindGen tạo ra một lược đồ với các định nghĩa complexTypesimpleType ghép lồng nhau nếu các kiểu chỉ được sử dụng một lần và tách riêng các định nghĩa nếu các kiểu được sử dụng nhiều lần. Trong trường hợp này, dùng định nghĩa kiểu lồng nhau dẫn đến một lược đồ chỉ có ba định nghĩa toàn cục: các kiểu phức hợp: địa chỉ (address) và đơn hàng và phần tử đơn hàng order. Lớp Address được sử dụng ở hai chỗ trong lớp Order (cho các địa chỉ thanh toán và vận chuyển), đó là lý do tại sao mà lớp đó được miêu tả bằng một định nghĩa toàn cầu riêng biệt trong lược đồ. (Lược đồ cho phép bạn sử dụng lại các định nghĩa chỉ khi chúng là toàn cầu). Các lớp khác trong cấu trúc dữ liệu Java (Khách hàng (Customer), Mục hàng (Item) và Vận chuyển (Shipping)) mỗi lớp được tham chiếu chỉ tại một điểm trong lớp Order, do đó các định nghĩa kiểu tương ứng được nhúng trực tiếp trong định nghĩa kiểu lược đồ order.

Một trong những đặc tính tốt đẹp hơn của BindGen là nó có thể tạo ra các tài liệu lược đồ từ Javadocs trong các lớp đầu vào. Bạn có thể xem tài liệu lược đồ trong Listing 2 cho từng trường với một Javadoc trong Listing 1 và cho mỗi kiểu toàn cầu tương ứng với một lớp với một Javadoc. Không phải tất cả các định dạng của các Javadoc đều có thể khớp với các thành phần của lược đồ theo xử lý mặc định của BindGen — và một số Javadoc, ví dụ như những javadocs về các phương thức truy cập “get”, có thể trông có vẻ kỳ cục khi được biến đổi thành tài liệu lược đồ — và một số Javadoc, ví dụ như những javadocs về các phương thức truy cập “get”, có thể trông có vẻ kỳ cục khi được biến đổi thành tài liệu lược đồ - nhưng tài liệu lược đồ kết quả có thể vô cùng hữu ích để làm rõ việc sử dụng đúng đắn các biểu diễn XML. Bạn thậm chí có thể định nghĩa một lớp định dạng (formatter) của riêng bạn dành cho các Javadoc được sử dụng như là tài liệu lược đồ, nếu bạn muốn thực hiện một số thay đổi lời văn trong quá trình biến đổi (chẳng hạn như việc loại bỏ đoạn mào đầu câu "Get ..." trong Javadocs của phương thức "get").

Đặc tính chuyển đổi Javadoc này chỉ hoạt động được nếu bạn có sẵn mã nguồn cho các lớp và cung cấp một đối số cho BindGen để báo cho nó biết một đường dẫn của thư mục gốc (hoặc các đường dẫn). Trong các mẫu dòng lệnh tôi đã cung cấp trước đó (xem Tạo liên kết và lược đồ mặc định-Generating the default binding and schema), đường dẫn nguồn được cung cấp là -s src.

Liên kết JiBX được tạo ra

Ngoài các định nghĩa lược đồ, BindGen cũng tạo ra một định nghĩa liên kết JiBX (là tệp tin binding.xml, trong trường hợp này). Định nghĩa liên kết cho các trình biên dịch liên kết của JiBX biết cách chuyển đổi giữa các lớp Java và XML như thế nào. Định nghĩa liên kết đó thực sự là kết quả chính của BindGen, với lược đồ được tạo ra từ việc liên kết. Các định nghĩa liên kết có đầy đủ các các chi tiết về các phép chuyển đổi được JiBX thực hiện, vì thế chúng nhất định là phải phức tạp. May mắn thay, bạn không cần phải hiểu định nghĩa liên kết để làm việc với JiBX khi sử dụng tạo lược đồ và liên kết của BindGen, vì vậy hướng dẫn này không trình bày các chi tiết.


Làm việc với các tài liệu XML

Trong phần này, bạn sẽ tìm hiểu về việc chạy trình biên dịch liên kết JiBX và sử dụng JiBX lúc đang chạy để làm việc với các tài liệu XML.

Chạy trình biên dịch liên kết JiBX

Để sử dụng định nghĩa liên kết được tạo ra trong khi làm việc với các tài liệu XML, trước hết bạn cần phải chạy công cụ trình biên dịch liên kết JiBX. Trình biên dịch liên kết thêm mã byte (bytecode) vào các tệp tin lớp đã biên dịch của bạn để thực sự triển khai thực hiện các phép biến đổi thành XML và từ XML, như định nghĩa liên kết đã chỉ rõ. Bạn phải chạy trình biên dịch liên kết mỗi khi bạn biên dịch lại lớp Java của bạn hoặc sửa đổi định nghĩa liên kết, vì vậy tốt nhất là thêm bước biên dịch liên kết như là một phần của quá trình xây dựng tiêu chuẩn của các dự án của bạn.

Trình biên dịch liên kết được bao gồm trong bản phân phối JiBX như là một phần của tệp tin jibx-bind.jar. Tài liệu JiBX cung cấp đầy đủ các chi tiết về các cách khác nhau để chạy trình biên dịch liên kết, bao gồm cả cách làm thế nào để bạn có thể chạy nó ở môi trường đang chạy chứ không phải là một phần của quá trình xây dựng. JiBX cũng cung cấp các trình cắm thêm cho Eclipse và IntelliJ IDEA để tự động chạy các trình biên dịch liên kết khi bạn đang làm việc trong các IDE này.

Với mục đích của hướng dẫn này, bạn nên làm đơn giản mọi việc và chỉ cần chạy trình biên dịch liên kết thông qua Ant, sử dụng đích bind (liên kết) trong tệp tin build.xml. Hình 2 cho thấy kết quả đầu ra mà bạn sẽ thấy khi bạn chạy đích này, giả định bạn đã chạy các đích compilebindgen. (Bạn cũng có thể chạy lần lượt tất cả ba đích này bằng cách liệt kê chúng theo thứ tự trên dòng lệnh: ant compile bindgen bind.)

Hình 2. Tác vụ bind của công cụ xây dựng Ant
Kết quả đầu ra của công cụ xây dựng Ant cho trình biên dịch liên kết

Sử dụng JiBX trong môi trường đang chạy chương trình

Listing 3 cho thấy một tài liệu thử nghiệm đơn giản khớp với lược đồ đã tạo ra, có trong mã đã tải về của hướng dẫn này, có tên là data.xml:

Listing 3. Tài liệu kiểm tra liên kết mặc định
<order orderNumber="12345678" orderDate="2008-10-18" shipDate="2008-10-22"
    xmlns="http://jibx.org/starter">
  <customer customerNumber="5678">
    <firstName>John</firstName>
    <lastName>Smith</lastName>
  </customer>
  <billTo>
    <street1>12345 Happy Lane</street1>
    <city>Plunk</city>
    <state>WA</state>
    <postCode>98059</postCode>
    <country>USA</country>
  </billTo>
  <shipping>PRIORITY_MAIL</shipping>
  <shipTo>
    <street1>333 River Avenue</street1>
    <city>Kirkland</city>
    <state>WA</state>
    <postCode>98034</postCode>
    <country>USA</country>
  </shipTo>
  <item quantity="1" price="5.99">
    <id>AC4983498512</id>
    <description>Left-handed widget</description>
  </item>
  <item quantity="2" price="9.50">
    <id>IW2349050499</id>
    <description>Right-handed widget</description>
  </item>
  <item quantity="1" price="8.95">
    <id>RC3000488209</id>
    <description>High-speed MP3 rewinder</description>
  </item>
</order>

Gói tải về cũng bao gồm một chương trình kiểm tra đơn giản, được hiển thị ở đây như Listing 4, để trình bày việc sử dụng JiBX cho cả hai tài liệu không tuần tự hóa (unmarshalling) và tuần tự hóa (marshalling). (Marshalling là quá trình sinh ra một biểu diễn XML của một đối tượng trong bộ nhớ, có thể bao gồm cả các đối tượng được liên kết với đối tượng ban đầu. Unmarshalling là quá trình ngược với tuần tự hóa, tức là xây dựng một đối tượng (và có thể là một đồ thị của các đối tượng liên kết với nhau) trong bộ nhớ từ một biểu diễn XML). Đích run của Ant thi hành chương trình thử nghiệm này bằng cách sử dụng tài liệu trong Listing 3 làm đầu vào và viết ra một bản sao kết quả tuần tự hóa đối tượng thành một tệp tin có tên là out.xml.

Listing 4. Chương trình thử nghiệm
public class Test
{
    /**
     * Unmarshal the sample document from a file, compute and set order total, then
     * marshal it back out to another file.
     * 
     * @param args 
     */
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("Usage: java -cp ... " +
                "org.jibx.starter.Test in-file out-file");
            System.exit(0);
        }
        try {
            
            // unmarshal customer information from file
            IBindingFactory bfact = BindingDirectory.getFactory(Order.class);
            IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
            FileInputStream in = new FileInputStream(args[0]);
            Order order = (Order)uctx.unmarshalDocument(in, null);
            
            // compute the total amount of the order
            float total = 0.0f;
            for (Iterator<Item> iter = order.getItems().iterator(); iter.hasNext();) {
                Item item = iter.next();
                total += item.getPrice() * item.getQuantity();
            }
            order.setTotal(new Float(total));
            
            // marshal object back out to file (with nice indentation, as UTF-8)
            IMarshallingContext mctx = bfact.createMarshallingContext();
            mctx.setIndent(2);
            FileOutputStream out = new FileOutputStream(args[1]);
            mctx.setOutput(out, null);
            mctx.marshalDocument(order);
            System.out.println("Processed order with " +  order.getItems().size() +
                " items and total value " + total);
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        } catch (JiBXException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

Hình 3 hiển thị kết quả mà bạn sẽ thấy khi chạy đích run:

Hình 3. Tác vụ run của công cụ xây dựng Ant
Kết quả đầu ra của công cụ xây dựng Ant từ việc chạy chương trình thử nghiệm

Bạn có thể rà soát tệp tin out.xml đã tạo ra để xem nó khớp với các đầu vào gốc được hiển thị trong Listing 3 như thế nào. Trừ ra khai báo không gian tên, thứ tự các thuộc tính và thuộc tính tổng giá trị (total) đã được thêm vào kết quả đầu ra (do chương trình thử nghiệm tính toán và thiết lập), hai tài liệu phải giống hệt nhau. Không phải lúc nào cũng được như vậy! JiBX, giống như hầu hết các dạng liên kết dữ liệu, chỉ làm việc với dữ liệu "quan trọng" trong tài liệu, có nghĩa là các giá trị được ứng dụng của bạn sử dụng. Các phần không quan trọng của tài liệu (như là khoảng trống bên trong thẻ bắt đầu và thẻ kết thúc, văn bản giữa các phần tử, và các lời ghi chú) bị mất khi bạn không sắp xếp theo thứ tự (unmarshal) một tài liệu. Một số lý do là các tài liệu đầu vào và đầu ra trong trường hợp này giống như mã của Listing 4 thiết lập định dạng đầu ra để sử dụng khoảng lùi đầu dòng là hai khoảng trống cho mỗi mức lồng nhau của phần tử XML, phù hợp với tài liệu đầu vào.

Người quan sát tinh mắt sẽ nhận thấy một sự khác biệt giữa đầu vào và đầu ra có vẻ quan trọng ở phần danh sách các mục hàng trong tài liệu kết quả đầu ra được hiển thị trong Listing 5:

Listing 5. Danh sách các mục hàng trong tài liệu kết quả
<item quantity="1" price="5.99">
    <id>AC4983498512</id>
    <description>Left-handed widget</description>
  </item>
  <item quantity="2" price="9.5">
    <id>IW2349050499</id>
    <description>Right-handed widget</description>
  </item>
  <item quantity="1" price="8.95">
    <id>RC3000488209</id>
    <description>High-speed MP3 rewinder</description>
  </item>

Nếu bạn so sánh dòng in đậm trong Listing 5 với dòng tương ứng trong Listing 3 của tài liệu đầu tiên, bạn có thể thấy rằng giá của mục hàng đã được thay đổi từ 9.50 thành 9.5, với số không đã được gỡ bỏ. Thế nhưng đây không phải là một lỗi. Dữ liệu giá mục hàng được biểu diễn bằng kiểu số dấu phẩy động (float) và theo quy ước của cả Java lẫn lược đồ XML, các số không phía trước dấu phẩy thập phân và các số không phía sau dấu phẩy thập phân là không quan trọng đối với một giá trị số dấu phẩy động.


Các tùy chỉnh BindGen

Trong phần này, bạn sẽ tìm hiểu cách làm thế nào tùy chỉnh hoạt động của BindGen để kiểm soát việc biểu diễn dữ liệu của XML, thay đổi kiểu dáng của các tên và các không gian tên và kiểm soát một số khía cạnh trong cấu trúc lược đồ.

Tùy chỉnh hoạt động của BindGen

BindGen hỗ trợ rất nhiều tùy chỉnh về tất cả các khía cạnh tạo liên kết và lược đồ. Tập hợp các tùy chỉnh sẽ áp dụng được chuyển đến BindGen dưới dạng một tài liệu XML, có các phần tử lồng nhau, phản chiếu cấu trúc mã Java của bạn. Listing 6 đưa ra một ví dụ đơn giản:

Listing 6. Ví dụ về các tùy chỉnh đơn giản
<custom>
  <package name="org.jibx.starter" property-access="true">
    <class name="Address" includes="street1 street2 city state postCode country"/>
    <class name="Item" excludes="description"/>
  </package>
</custom>

Ví dụ này làm việc với một gói mã Java đơn giản, vì thế Listing 6 sử dụng chỉ một phần tử <package> là con của phần tử gốc <custom>. Các phần tử tùy chỉnh <package><class> sử dụng các thuộc tính tên tương ứng với phần tử <package> chứa nó, vì thế trong ví dụ của Listing 6 chỉ cần dùng một tên lớp đơn giản cho mỗi phần tử <class>. Các phần tử <package> có thể được lồng bên trong một phần tử khác, do đó nếu bạn đang làm việc với các lớp xuyên qua một hệ phân cấp các gói, thì việc xử lý một tùy chọn bất kỳ, sử dụng các phần tử <package> lồng nhau thật dễ dàng. Cấu trúc lồng nhau đặc biệt thuận lợi vì nhiều thuộc tính tuỳ chỉnh được thừa kế xuyên qua việc lồng phần tử, như tôi sẽ trình bày sau trong phần này. Sử dụng cấu trúc lồng nhau là tùy chọn, vì thế — bạn có thể bỏ qua hoàn toàn các phần tử <package> và sử dụng trực tiếp các phần tử <class> với các tên lớp đủ phân biệt, nếu bạn thích.

Một tệp tin tuỳ chỉnh được chuyển tới BindGen thông qua một tham số dòng lệnh, dưới dạng đường-dẫn-đến-tệp-tin -c. Các tuỳ chỉnh luôn luôn là tùy chọn và bạn không bao giờ cần phải sử dụng một tệp tin tuỳ chỉnh trừ khi bạn muốn thay đổi hành vi mặc định của BindGen.

Kiểm soát BindGen làm việc với mã của bạn như thế nào

BindGen làm những việc hợp lý khi xử lý các lớp Java theo mặc định, nhưng có những hạn chế về những gì có thể được thực hiện nếu không có hướng dẫn thêm của người sử dụng. Ví dụ, xử lý mặc định là bao gồm mọi trường vào biểu diễn XML trừ các trường tĩnh (static), tạm thời (transient) hoặc không thay đổi nữa (final). Cách tiếp cận này hoạt động tốt với các lớp biểu diễn các đối tượng dữ liệu đơn giản; tuy nhiên, nếu các lớp của bạn có các thông tin trạng thái hoặc các giá trị phải được tính toán, bạn có thể đi đến kết cục là một biểu diễn XML bao gồm cả các giá trị mà bạn không muốn để lộ ra bên ngoài lớp đó.

Các tùy chỉnh cho phép bạn có hai cách để kiểm soát những gì mà BindGen sử dụng trong biểu diễn XML. Trước tiên, bạn có thể dễ dàng chuyển sang sử dụng các phương thức truy nhập getXXX(), setXXX()isXXX() theo phong cách bean chứ không phải là trực tiếp truy nhập các trường. Thứ hai, bạn có thể chọn hoặc liệt kê các giá trị bạn muốn có trong biểu diễn XML của một lớp hoặc liệt kê các giá trị bạn muốn loại bỏ. Các tùy chỉnh trong Listing 6 giải thích cả hai kỹ thuật này.

Các phép chuyển đổi một chiều

Hướng dẫn này sử dụng JiBX cho các phép chuyển đổi hai chiều giữa các cấu trúc dữ liệu Java và các tài liệu XML. BindGen cũng hỗ trợ tạo ra các phép chuyển đổi một chiều, tiện lợi hơn trong một số trường hợp. Ví dụ, các lớp đối tượng biểu diễn một giá trị nói chung là không thay đổi và chỉ định nghĩa các trường không thay đổi (final) và các phương thức truy nhập đọc ("get"). Điều này làm cho các lớp đối tượng giá trị khó sử dụng cho các phép chuyển đổi hai chiều với BindGen. Nếu thay vì hai chiều, bạn ra lệnh cho BindGen tạo ra một phép chuyển đổi chỉ có kết quả một chiều, nó sẽ làm việc tốt với cả các trường cũng như các thuộc tính, tùy theo bạn thích gì. Để tạo ra một phép chuyển đổi một chiều, hãy sử dụng thuộc tính direction="output" hay direction="input" hoặc <custom> của phần tử gốc của các tùy chỉnh.

Phần tử <package> trong Listing 6 sử dụng một thuộc tính property-access="true" để ra lệnh cho BindGen tìm kiếm các thuộc tính phong cách bean được định nghĩa bởi các phương thức truy nhập công cộng, không tĩnh (public, nonstatic) chứ không phải là tìm các trường, khi xác định những giá trị nào sẽ đưa vào biểu diễn XML. Thuộc tính này là một ví dụ về thiết lập tùy chỉnh có thừa kế để áp dụng cho tất cả mọi thứ lồng vào bên trong phần tử có thuộc tính này. Trong ví dụ của Listing 6 thiết lập áp dụng cho hai phần tử <class> lồng nhau. Nó cũng áp dụng cho tất cả các lớp khác trong gói mặc dù không có phần tử tùy chỉnh <class> nào có mặt dành cho các lớp khác đó. Bên cạnh việc xác định làm thế nào để tìm các giá trị từ biểu diễn lớp, việc thiết lập property-access cũng điều khiển cách thức mà mã JiBX được tạo ra sẽ truy nhập các giá trị như thế nào — trực tiếp từ các trường hay gọi các phương thức truy nhập.

Phần tử <class> đầu tiên trong Listing 6 sử dụng một thuộc tính includes="street1 street2 city state postCode country" để liệt kê các giá trị cụ thể từ trong lớp mà BindGen cần phải đưa vào trong biểu diễn XML. Phần tử <class> thứ hai trong Listing này sử dụng một thuộc tính excludes="description" để liệt kê các giá trị phải loại bỏ khỏi biểu diễn XML. Vì bạn đang sử dụng cách truy nhập thuộc tính chứ không phải là truy nhập trường để lấy các giá trị nên các tên này phải khớp với các thuộc tính được xác định bởi các phương thức truy nhập get/set/is. Nếu bạn đang sử dụng các trường, các tên của giá trị sẽ phải khớp với các tên trường.

Đích Ant custgen1 chạy BindGen bằng cách sử dụng các tùy chỉnh của Listing 6. Đích này là một đích thay thế cho đích bindgen được hiển thị ở trên, vì thế để chạy xong hoàn toàn quá trình xây dựng bạn cần sử dụng dòng lệnh Ant: ant compile custgen1 bind. Listing 7 hiển thị định nghĩa kiểu mục hàng từ lược đồ đã tạo ra khi đích này đang chạy:

Listing 7. Một đoạn kết quả của lược đồ đã tùy chỉnh
<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
  <xs:complexType>
    <xs:sequence>
      <xs:element type="xs:string" name="id" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:int" use="required" name="quantity"/>
    <xs:attribute type="xs:float" use="required" name="price"/>
  </xs:complexType>
</xs:element>

Bạn có thể nhận thấy từ Listing 7 rằng bây giờ các mô tả đã biến mất khỏi biểu diễn của lược đồ như các tùy chỉnh đã chỉ rõ.

Bạn cần phải sử dụng một tài liệu XML khác làm đầu vào khi sử dụng tùy chỉnh này, vì phần tử <description> có mặt trong XML đầu tiên không còn được sử dụng nữa. Đích Ant run1 chạy chương trình thử nghiệm bằng cách sử dụng một đầu vào data1.xml và tạo ra out1.xml như là kết quả đầu ra. Bạn cũng có thể chạy toàn bộ chuỗi công việc, từ biên dịch mã nguồn đến chạy chương trình thử nghiệm, với đích Ant custom1.

Kiểm soát việc tạo cá thể

Cũng có thể kiểm soát việc tạo ra một cá thể trong khi phi tuần tự hóa bằng cách sử dụng các tùy chỉnh. Theo mặc định, JiBX chờ đợi sẽ có một hàm tạo (constructor) không đối số (mặc định) được định nghĩa cho mỗi lớp (mà trình biên dịch Java tự động tạo ra, nếu bạn không định nghĩa bất kỳ hàm tạo nào khác). Khi cần đến một cá thể mới của lớp trong khi không tuần tự hóa, JiBX sử dụng hàm tạo không đối số đó để tạo ra cá thể. Nếu một số lớp của bạn chỉ định nghĩa các hàm tạo có đối số, bạn có thể sử dụng các tùy chỉnh BindGen để làm cho JiBX có thể sử dụng chúng. Một cách để làm điều này là định nghĩa một phương thức nhà máy sản xuất (factory) dùng để tạo ra các cá thể của các lớp và sử dụng một thuộc tính factory="xxx" của phần tử tùy chỉnh <class> để cung cấp tên đủ phân biệt (thông tin về phần tiếp đầu tên gói, tên lớp) của một phương thức tĩnh trả về một cá thể của lớp. Bạn cũng có thể chỉ cần thêm thuộc tính add-constructors="true" của phần tử gốc <custom> để nó tạo ra một liên kết thêm các hàm tạo không đối số cho các lớp khi cần thiết. Cách tiếp cận thứ hai này hoạt động tốt với các lớp dữ liệu bình thường, nhưng bạn vẫn cần phải cung cấp một phương thức nhà máy sản xuất cho các giao diện hoặc các lớp trừu tượng (abstract) bất kỳ (vì có thể không bao giờ được trực tiếp tạo ra). Tất nhiên, nếu bạn đang tạo ra một liên kết chỉ một chiều kết quả (xem Các phép chuyển đổi một chiều ở thanh bên cạnh), việc tạo các cá thể không còn là một vấn đề nữa và bạn không cần phải lo lắng về các hàm tạo.

Các tùy chỉnh khác để làm việc với các lớp đầu vào

BindGen hỗ trợ nhiều tùy chỉnh khác được sử dụng để kiểm soát nó làm việc với các lớp Java đầu vào như thế nào. Ví dụ, nếu bạn sử dụng một quy ước đặt tên cho các tên trường Java của bạn, bạn có thể cấu hình BindGen để bỏ qua các chuỗi tiền tố hoặc hậu tố cụ thể bằng cách sử dụng các thuộc tính strip-prefixes hoặc strip-suffixes. (Ví dụ, để bỏ qua các tiền tố m_s_ bạn sử dụng thuộc tính strip-prefixes="m_ s_"). Các sửa đổi này đối với các tên trường được áp dụng trước khi các trường được khớp với các tên giá trị sử dụng trong các tùy chỉnh khác và lẽ tự nhiên, cũng chỉ áp dụng khi các tên XML được tạo ra từ các tên trường.

Bạn cũng có thể tùy chỉnh việc xử lý các trường riêng lẻ hoặc các thuộc tính bean riêng lẻ trong một lớp bằng cách sử dụng các phần tử <value> lồng bên trong. Bạn sẽ thấy cách làm việc với các phần tử tùy chỉnh giá trị ấy như thế nào trong một ví dụ dưới đây.

Kiểm soát biểu diễn XML

Bên cạnh việc kiểm soát BindGen diễn giải mã Java của bạn như thế nào, bạn có thể sử dụng các tùy chỉnh để kiểm soát biểu diễn dữ liệu bằng XML. Các tùy chỉnh XML bao gồm biểu diễn thực tế (như là một phần tử hoặc một thuộc tính) của các giá trị, thứ tự và tên của các phần tử và các thuộc tính, một giá trị là tùy chọn hay cần phải có và nhiều thứ nữa.

Ví dụ tùy chỉnh trong Listing 6 ở trên giải thích một tùy chỉnh XML dưới dạng của thuộc tính includes="street1 street2 city state postCode country" sử dụng cho phần tử <class> đầu tiên. Tôi đã thảo luận cách thức tùy chỉnh này chọn các giá trị trong các lớp sẽ được đưa vào trong biểu diễn XML như thế nào. Nó cũng kiểm soát biểu diễn XML trong việc bố trí thứ tự trong đó các giá trị đã được liệt kê sẽ trở thành thứ tự trong đó chúng xuất hiện trong biểu diễn XML. Đó không phải là một vấn đề đáng kể đối với các thuộc tính (vốn luôn luôn được coi là không có thứ tự trong XML), nhưng lại là điều quan trọng đối với các phần tử.

Nếu bạn không xác định thứ tự của các giá trị bằng cách sử dụng một thuộc tính includes của phần tử tùy chỉnh <class>, BindGen tạo ra các giá trị theo thứ tự mà chúng được gửi đi bằng cách sử dụng phản chiếu Java của các lớp. Đối với hầu hết các trình biên dịch Java và các JVM, thứ tự phản chiếu này sẽ khớp với thứ tự của các định nghĩa trong mã nguồn Java. Tuy nhiên, các trình biên dịch Java và các JVM không bắt buộc phải duy trì thứ tự này từ mã nguồn, do đó một số trình biên dịch hoặc các JVM có thể làm cho BindGen thay đổi thứ tự của các phần tử con. Nếu bạn muốn chắc chắn biểu diễn XML luôn luôn như nhau, bất kể dùng trình biên dịch Java hay JVM nào, thuộc tính includes sẽ mang lại cho bạn một biện pháp dễ dàng để cố định thứ tự này.

Bạn cũng có thể kiểm soát biểu diễn XML của một giá trị bằng cách sử dụng thuộc tính includes. BindGen cho phép sử dụng các ký tự cờ báo thêm vào trước mỗi tên trong danh sách để biểu thị cách biểu diễn: @ đứng trước một thuộc tính và / đứng trước một thuộc tính. Vì vậy, nếu bạn thay đổi tùy chỉnh includes="street1 street2 city state @postCode country" trong Listing 6, biểu diễn giá trị của mã số bưu điện (postCode) sẽ thay đổi từ một phần tử con thành một thuộc tính.

Kiểm soát vị thế là cần phải có hay là tùy chọn

Kiểm soát một giá trị được coi là tùy chọn hay cần phải có thực hiện bằng một tùy chỉnh dễ dàng khác, thông qua sử dụng các thuộc tính requiredsoptionals của phần tử <class>. Giống như với thuộc tính includes bạn có thể thêm một ký tự cờ báo vào trước các tên trong các danh sách các giá trị cần phải có (requireds) và các giá trị tùy chọn (optionals) để biểu thị chúng cần phải được biểu diễn như một phần tử con hay một thuộc tính.

Theo mặc định, BindGen coi tất cả các giá trị nguyên thủy và các giá trị đối tượng đơn giản (các lớp có kiểu tương đương trực tiếp của XML, không phải là String) như là các thuộc tính và coi tất cả các giá trị đối tượng phức tạp như là các phần tử con. Tất cả các giá trị nguyên thủy được coi là giá trị cần phải có và tất cả các giá trị đối tượng được coi là các giá trị tùy chọn. Ngoài việc viết đè lên các mặc định này ở mức tùy chỉnh <class> bằng cách sử dụng các phần tử includes, requiredsoptionals, bạn có thể thay đổi biểu diễn mặc định, chỉ sử dụng các phần tử cho tất cả các giá trị bằng cách thiết lập một thuộc tính value-style="element" ở mọi mức tùy chỉnh (các phần tử (<custom>, <package>, hay <class>). Bạn cũng có thể sử dụng thuộc tính require để kiểm soát những kiểu nào cần được coi là các giá trị cần phải có trong XML:

  • require="none" làm cho mọi thứ đều là tùy chọn.
  • require="primitives" là mặc định, chỉ làm cho các giá trị nguyên thủy thành cần phải có.
  • require="objects" đảo ngược mặc định, làm cho các kiểu nguyên thủy thành tùy chọn còn các kiểu đối tượng thành cần phải có.
  • require="all" coi tất cả các giá trị đều là cần phải có theo mặc định.

Listing 8 hiển thị tệp tin tùy chỉnh custom2.xml từ thư mục tải xuống dwcode1 của hướng dẫn, minh họa một số đặc tính mà tôi đã thảo luận trong phần này:

Listing 8. Tùy chỉnh thứ tự, vị thế “cần phải có” và biểu diễn XML
<custom property-access="true">
  <package name="org.jibx.starter">
    <class name="Address" includes="street1 street2 city @state @postCode country"
        requireds="street1 city"/>
    <class name="Customer" includes="customerNumber firstName lastName"
        requireds="lastName firstName /customerNumber"/>
    <class name="Item" excludes="description" requireds="@id quantity price"/>
    <class name="Order" requireds="/orderNumber customer billTo shipping orderDate"/>
  </package>
</custom>

Bạn có thể thử tập hợp các tùy chỉnh này bằng cách sử dụng đích Ant custgen2 (ant compile custgen2 bind, để chạy đầy đủ quá trình xây dựng). Listing 9 trình bày một số phần chọn lọc trong lược đồ đã tạo ra khi sử dụng các tùy chỉnh này, hiển thị thứ tự của kết quả, vị thế là cần phải có (với minOccurs="0" đối với các phần tử tùy chọn, theo mặc định là giá trị cần phải có trong lược đồ và use="required" đối với các thuộc tính cần phải có, theo mặc định là tùy chọn trong lược đồ) và biểu diễn của thuộc tính hay phần tử:

Listing 9. Lược đồ được tạo ra khi sử dụng các tùy chỉnh
<xs:complexType name="order">
  <xs:annotation>
    <xs:documentation>Order information.</xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element type="xs:long" name="orderNumber">
      <xs:annotation>
        <xs:documentation>Get the order number.</xs:documentation>
      </xs:annotation>
    </xs:element>
    <xs:element name="customer">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:long" name="customerNumber"/>
          <xs:element type="xs:string" name="firstName"/>
          <xs:element type="xs:string" name="lastName"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
    ...
  </xs:sequence>
  <xs:attribute type="xs:date" use="required" name="orderDate"/>
  <xs:attribute type="xs:date" name="shipDate"/>
  <xs:attribute type="xs:float" name="total"/>
</xs:complexType>
<xs:element type="tns:order" name="order"/>
<xs:complexType name="address">
  <xs:annotation>
    <xs:documentation>Address information.</xs:documentation>
  </xs:annotation>
  <xs:sequence>
    <xs:element type="xs:string" name="street1"/>
    <xs:element type="xs:string" name="street2" minOccurs="0"/>
    <xs:element type="xs:string" name="city"/>
    <xs:element type="xs:string" name="country" minOccurs="0"/>
  </xs:sequence>
  <xs:attribute type="xs:string" name="state"/>
  <xs:attribute type="xs:string" name="postCode"/>
</xs:complexType>

Sau khi biên dịch các liên kết bằng cách sử dụng tác vụ Ant bind, bạn có thể kiểm tra điều này bằng cách sử dụng tác vụ run2 dùng tài liệu thử nghiệm data2.xml làm đầu vào và tạo ra một kết quả đầu ra là out2.xml. Bạn cũng có thể chạy toàn bộ chuỗi tác vụ từ biên dịch đến kiểm thử với đích custom2. Listing 10 cho thấy tài liệu thử nghiệm:

Listing 10. Tài liệu thử nghiệm khớp với các tùy chỉnh
<order orderDate="2008-10-18" shipDate="2008-10-22" xmlns="http://jibx.org/starter">
  <orderNumber>12345678</orderNumber>
  <customer>
    <customerNumber>5678</customerNumber>
    <firstName>John</firstName>
    <lastName>Smith</lastName>
  </customer>
  <billTo state="WA" postCode="98059">
    <street1>12345 Happy Lane</street1>
    <city>Plunk</city>
    <country>USA</country>
  </billTo>
  <shipping>PRIORITY_MAIL</shipping>
  <shipTo state="WA" postCode="98034">
    <street1>333 River Avenue</street1>
    <city>Kirkland</city>
  </shipTo>
  <item quantity="1" price="5.99" id="8394983498512"/>
  <item quantity="2" price="9.50" id="9912349050499"/>
  <item quantity="1" price="8.95" id="1293000488209"/>
</order>

So sánh Listing 10 với tài liệu thử nghiệm ban đầu, được hiển thị trong Listing 3, để xem tùy chỉnh của bạn đã làm thay đổi biểu diễn dữ liệu XML như thế nào (bao gồm cả việc thay đổi dạng của các dòng biểu diễn một mục hàng thành các phần tử rỗng, một cách biểu diễn cô đọng hơn nhiều so với tài liệu ban đầu).

Kiểm soát các tên và các không gian tên

Các tên của Java thông thường sử dụng kiểu dáng “bướu lạc đà” (camelcase): các tên hầu hết là chữ thường nhưng chữ cái đầu tiên của mỗi từ được viết hoa. Đối với các tên trường hoặc tên thuộc tính, chỉ áp dụng viết chữ hoa ban đầu đối với các từ sau từ đầu tiên (dẫn đến các tên có dạng như là postCodecustomerNumber). Các tên của XML không được tiêu chuẩn hóa và có vài kiểu dáng khác nhau thường được sử dụng. Trong đó gồm có kiểu dáng “bướu lạc đà” với chữ thường đầu tiên (giống kiểu dáng của tên trường và tên thuộc tính Java), kiểu dáng “bướu lạc đà” với chữ viết hoa đầu tiên (giống kiểu dáng của tên lớp Java), kiểu dáng phân cách vạch ngang (các từ được phân cách bằng dấu gạch ngang), kiểu dáng phân cách dấu chấm (các từ được phân cách bằng các dấu chấm) và kiểu dáng phân cách gạch dưới (các từ được phân cách bằng dấu gạch dưới).

BindGen giả định dùng kiểu dáng bướu lạc đà cho các tên XML theo mặc định, nhưng bạn có thể dễ dàng thay đổi điều này bằng cách thiết lập một thuộc tính name-style ở bất kỳ mức tùy chỉnh nào (phần tử (<custom>, <package>, hay <class>). Các giá trị hợp lệ cho thuộc tính này khớp với các kiểu dáng XML khác nhau đã được liên kê ở trên:

  • Kiểu bướu lạc đà mặc định).
  • Kiểu bướu lạc đà, chữ hoa đầu tiên.
  • Có dấu nối ở giữa.
  • Có nhiều dấu chấm.
  • Có dấu gạch dưới.

Bạn cũng có thể thiết lập tên XML cho một giá trị bằng cách sử dụng riêng một tùy chỉnh cho giá trị đó. Việc sử dụng một tùy chỉnh giá trị riêng lẻ sẽ cho phép bạn toàn quyền kiểm soát trên cả hai mặt, làm thế nào để truy nhập giá trị đó và biểu diễn XML của giá trị đó như thế nào. Listing 11 đưa ra một số ví dụ về việc sử dụng các phần tử tùy chỉnh cho các giá trị riêng lẻ, dựa trên cùng một mã mẫu giống nhau mà bạn đã thấy trong ví dụ ở trên:

Listing 11. Tùy chỉnh các tên và các không gian tên
<custom property-access="true" name-style="hyphenated" namespace="http://jibx.org/custom"
    namespace-style="fixed">
  <package name="org.jibx.starter">
    <class name="Address" includes="street1 street2 city @state @postCode country"
        requireds="street1 city"/>
    <class name="Customer" includes="customerNumber firstName lastName"
        requireds="lastName firstName /customerNumber"/>
    <class name="Item" excludes="description" requireds="@id quantity price"/>
    <class name="Order" requireds="orderNumber customer billTo shipping orderDate">
     <value property-name="orderNumber" element="order-num"/>
      <value property-name="items" item-name="line-item" element="order-items"/>
    </class>
  </package>
</custom>

Tùy chỉnh giá trị đầu tiên trong Listing 11 dành cho thuộc tính orderNumber bên trong phần tử <class name="Order"...> Bằng cách sử dụng một thuộc tính element="order-num", tùy chỉnh orderNumber ra lệnh cho BindGen diễn tả giá trị này như là một phần tử, chứ không phải dưới dạng thuộc tính mặc định được sử dụng cho một giá trị nguyên thủy. Tùy chỉnh thứ hai là dành cho thuộc tính sưu tập các mục hàng. Tùy chỉnh này sử dụng cả hai thuộc tính item-nameelement. Thuộc tính item-name kiểm soát tên được sử dụng cho các giá trị riêng lẻ mà sưu tập biểu diễn, trong khi thuộc tính element bắt buộc sử dụng tên đã cung cấp như là một phần tử bao gói các giá trị trong sưu tập.

XML không có các không gian tên

Tất cả các ví dụ của hướng dẫn sử dụng các không gian tên XML vì việc sử dụng các không gian tên thường được coi là một thói quen thực tế tốt nhất cho việc trao đổi dữ liệu. Nếu bạn muốn làm việc với XML mà không có các không gian tên, bạn có thể sử dụng một thuộc tính namespace-style="none" ở bất kỳ mức tùy chỉnh nào để tắt hoàn toàn các không gian tên cho tất cả các thành phần lồng bên trong.

Các tùy chỉnh của Listing 11 cũng định nghĩa các không gian tên được sử dụng trong tài liệu XML. Các ví dụ trước đó dựa vào BindGen xử lý mặc định các không gian tên, cụ thể là lấy URI không gian tên dùng trong biểu diễn XML của mã Java trong gói Java. Việc xử lý mặc định này đã chuyển đổi gói org.jibx.starter thành URI không gian tên http://jibx.org/starter. Trong Listing 11, không gian tên được tùy chỉnh bằng cách thêm một cặp hai thuộc tính — namespace="http://jibx.org/custom"namespace-style="fixed" — trên phần tử gốc <custom>. Thuộc tính đầu tiên định nghĩa không gian tên cơ sở, còn thuộc tính thứ hai ngăn chặn hành vi thông thường là sửa đổi không gian tên dựa vào gói Java. Cả hai thuộc tính này được thừa kế xuyên qua các phần tử tùy chỉnh lồng vào nhau, vì thế chúng có thể dễ dàng được đặt vào phần tử <package> thay vì phần tử <custom>.

Bạn có thể thử nghiệm tùy chỉnh trong Listing 11 bằng cách sử dụng đích Ant custgen3 để tạo ra lược đồ và liên kết và đích run3 để chạy một phép thử nghiệm (sau khi sử dụng đích bind tiêu chuẩn để chạy trình biên dịch liên kết JiBX — hoặc chỉ cần sử dụng đích full3 để thực hiện toàn bộ chuỗi tác vụ). Listing 12 hiển thị tài liệu đầu vào được sử dụng với mã thử nghiệm:

Listing 12. Mẫu XML với các tên và các không gian tên đã được tùy chỉnh
<order order-date="2008-10-18" ship-date="2008-10-22" xmlns="http://jibx.org/custom">
  <order-num>12345678</order-num>
  <customer>
    <customer-number>5678</customer-number>
    <first-name>John</first-name>
    <last-name>Smith</last-name>
  </customer>
  <bill-to state="WA" post-code="98059">
    <street1>12345 Happy Lane</street1>
    <city>Plunk</city>
    <country>USA</country>
  </bill-to>
  <shipping>PRIORITY_MAIL</shipping>
  <ship-to state="WA" postCode="98034">
    <street1>333 River Avenue</street1>
    <city>Kirkland</city>
  </ship-to>
  <order-items>
    <line-item quantity="1" price="5.99" id="AC4983498512"/>
    <line-item quantity="2" price="9.50" id="IW2349050499"/>
    <line-item quantity="1" price="8.95" id="RC3000488209"/>
  </order-items>
</order>

Nếu bạn so sánh mẫu Listing 12 với mẫu Listing 10 bạn sẽ thấy biểu diễn XML đã thay đổi như thế nào bởi các tùy chỉnh mới nhất.

Tùy chỉnh các biểu diễn lược đồ

Bây giờ bạn đã thấy các tùy chỉnh của BindGen có thể thay đổi biểu diễn XML của dữ liệu Java của bạn như thế nào. Các tùy chỉnh cũng có thể được sử dụng để kiểm soát một số khía cạnh của cấu trúc lược đồ thực tế.

Hãy nhớ lại rằng BindGen mặc định sẽ sử dụng các định nghĩa được lồng nhau hơn là các kiểu và các phần tử toàn cục. Nếu bạn xem lại lược đồ được tạo ra trong Listing 9 bạn sẽ thấy cấu trúc lồng nhau này. Lược đồ chỉ sử dụng ba định nghĩa toàn cầu: các kiểu phức hợp địa chỉ (address) và đơn hàng (order) và phần tử order. Các lớp khác trong các cấu trúc dữ liệu Java (Customer, Item, và Shipping) mỗi thứ được tham chiếu chỉ tại một điểm trong lớp Order do đó các định nghĩa kiểu tương ứng được nhúng trực tiếp trong định nghĩa kiểu lược đồ order.

Bạn có thể thay đổi kiểu dáng của lược đồ bằng cách sử dụng một thuộc tính force-mapping="true" trên bất kỳ các phần tử tùy chỉnh lồng nhau nào. Listing13 cho thấy tệp tin tùy chỉnh custom4.xml, trong đó bổ sung thêm sự thay đổi này cho các tùy chỉnh custom2.xml khớp với lược đồ đã tạo ra trong Listing 9:

Listing 13. Tùy chỉnh cho cấu trúc của lược đồ
<custom property-access="true" force-mapping="true">
  <package name="org.jibx.starter">
    <class name="Address" includes="street1 street2 city @state @postCode country"
        requireds="street1 city"/>
    <class name="Customer" includes="customerNumber firstName lastName"
        requireds="lastName firstName /customerNumber"/>
    <class name="Item" excludes="description" requireds="@id quantity price"/>
    <class name="Order" requireds="/orderNumber customer billTo shipping orderDate"/>
  </package>
</custom>

Listing 14 hiển thị cấu trúc lược đồ kết quả (là tệp starter.xsd được tạo ra bằng cách chạy đích custgen4). Phiên bản này của lược đồ biểu diễn cùng một cấu trúc tài liệu XML giống như là lược đồ trong Listing 9 nhưng bao gồm các định nghĩa kiểu riêng biệt khớp với mỗi lớp Java.

Listing 14. Cấu trúc lược đồ đã tùy chỉnh
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://jibx.org/starter" elementFormDefault="qualified"
    targetNamespace="http://jibx.org/starter">
  <xs:simpleType name="shipping">
    <xs:annotation>
      <xs:documentation>Supported shipment methods. The "INTERNATIONAL" shipment
      methods can only be used for orders with shipping addresses outside the U.S., and
      one of these methods is required in this case.</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      ...
    </xs:restriction>
  </xs:simpleType>
  <xs:complexType name="item">
    <xs:annotation>
      <xs:documentation>Order line item information.</xs:documentation>
    </xs:annotation>
    <xs:sequence/>
    <xs:attribute type="xs:string" use="required" name="id"/>
    <xs:attribute type="xs:int" use="required" name="quantity"/>
    <xs:attribute type="xs:float" use="required" name="price"/>
  </xs:complexType>
  <xs:element type="tns:order" name="order"/>
  <xs:complexType name="address">
    <xs:annotation>
      <xs:documentation>Address information.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element type="xs:string" name="street1"/>
      <xs:element type="xs:string" name="street2" minOccurs="0"/>
      <xs:element type="xs:string" name="city"/>
      <xs:element type="xs:string" name="country" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="state"/>
    <xs:attribute type="xs:string" name="postCode"/>
  </xs:complexType>
  <xs:complexType name="customer">
    <xs:annotation>
      <xs:documentation>Customer information.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element type="xs:long" name="customerNumber"/>
      <xs:element type="xs:string" name="firstName"/>
      <xs:element type="xs:string" name="lastName"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="order">
    <xs:annotation>
      <xs:documentation>Order information.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element type="xs:long" name="orderNumber">
        <xs:annotation>
          <xs:documentation>Get the order number.</xs:documentation>
        </xs:annotation>
      </xs:element>
      <xs:element type="tns:customer" name="customer"/>
      <xs:element type="tns:address" name="billTo"/>
      <xs:element type="tns:shipping" name="shipping"/>
      <xs:element type="tns:address" name="shipTo" minOccurs="0"/>
      <xs:element type="tns:item" name="item" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute type="xs:date" use="required" name="orderDate"/>
    <xs:attribute type="xs:date" name="shipDate"/>
    <xs:attribute type="xs:float" name="total"/>
  </xs:complexType>
</xs:schema>

Các lược đồ theo kiểu được hiển thị trong Listing 14, được gọi là các lược đồ kiểu "Cửa chớp lật" (Venetian Blind) được sử dụng phổ biến trong các định nghĩa cấu trúc XML phức hợp. Bằng cách tách riêng từng định nghĩa kiểu, lược đồ kiểu này cho phép bạn dễ dàng sử dụng lại các cấu trúc thành phần khi sửa đổi hoặc mở rộng một lược đồ. Tính linh hoạt của lược đồ kiểu “Venetian Blind” có thể không quan trọng nếu bạn chỉ lập kế hoạch để sử dụng mã Java của bạn làm cơ sở cho bất kỳ thay đổi thêm nào khác (chạy lại BindGen mỗi khi thay đổi mã của bạn), nhưng có thể sẽ tốt hơn, nếu bạn dự định sử dụng lược đồ làm cơ sở cho các phát triển tiếp theo.


Các tham số dòng lệnh BindGen

BindGen hỗ trợ một số tham số dòng lệnh ngoài những tham số đã dùng trong mã hướng dẫn. Bảng 1 liệt kê các tùy chọn quan trọng nhất:

Bảng 1. Các tùy chọn dòng lệnh BuildGen
CommandPurpose
-b nameTên tệp tin định nghĩa liên kết gốc được tạo ra (tên mặc định là binding.xml).
-c pathĐường dẫn đến tệp tin tùy chỉnh đầu vào.
-n uri=name,...Cho cặp URI không gian tên lược đồ và tên-tệp tin (mặc định tạo các tên tệp tin từ các URI không gian tên lược đồ).
-p path,...Các đường dẫn để nạp các tệp tin lớp Java (mặc định là đường dẫn được sử dụng để chạy BindGen).
-s path,...Các đường dẫn để nạp các tệp mã nguồn Java (nguồn không được sử dụng theo mặc định).
-t pathĐường dẫn thư mục đích dành cho kết quả đầu ra được tạo ra (mặc định là thư mục hiện tại).
-wXoá tất cả các tệp tin khỏi thư mục đích trước khi sinh ra kết quả đầu ra (bỏ qua nếu thư mục đích cũng là thư mục hiện tại)

Bạn cũng có thể chuyển cho BindGen các tùy chỉnh toàn cục dưới dạng các tham số dòng lệnh mà không cần phải tạo ra một tệp tin tùy chỉnh, bằng cách sử dụng kí hiệu -- làm một tiền tố dành riêng cho giá trị của thuộc tính tùy chỉnh. Ví dụ để thiết lập cũng các tùy chọn toàn cầu giống như đã dùng trong các tùy chỉnh của Listing 13, bạn cần thêm --property-access=true --force-mapping=true vào dòng lệnh của BindGen . Không cần dùng dấu nháy kép cho giá trị thuộc tính khi bạn sử dụng kỹ thuật này. Nếu bạn muốn thiết lập một tùy chỉnh cho một danh sách nhiều giá trị, hãy sử dụng các dấu phẩy để phân cách từng giá trị riêng lẻ chứ không phải các khoảng trống (Ví dụ, để bỏ qua các tiền tố m_s_ trước các tên trường, bạn sử dụng tham số dòng lệnh --strip-prefixes=m_,s_).


Tiến xa hơn

Trong hướng dẫn này, bạn đã học những điều căn bản về cách sử dụng JiBX để tạo ra một định nghĩa lược đồ XML từ mã Java của bạn và sau đó chuyển đổi các tài liệu XML khớp với lược đồ này thành cấu trúc dữ liệu Java và ngược lại. Có rất nhiều tùy chỉnh khác mà bạn có thể sử dụng để kiểm soát việc tạo lược đồ, ngoài những thứ mà tôi đã trình bày trong hướng dẫn này. Các tài liệu JiBX cung cấp đầy đủ các chi tiết về tất cả các lựa chọn tùy chỉnh ấy, cùng với nhiều ví dụ về việc tạo lược đồ từ mã Java.

Bạn thậm chí có thể tiến xa hơn với JiBX bằng cách làm việc với các định nghĩa liên kết thực tế; nó sẽ cho phép bạn kiểm soát tất cả các bước của quá trình biến đổi. Bạn có thể dễ dàng thêm mã riêng của bạn mà sẽ được thực hiện như là một phần của các phép biến đổi, khi sử dụng các móc nối phần mở rộng của người dùng xây dựng vào trong định nghĩa liên kết. Bạn thậm chí có thể tự viết các mã lệnh tuần tự hóa và không tuần tự hóa tùy biến riêng của bạn để chúng có thể kiểm soát có chọn lọc các mã được JiBX tạo ra để xử lý các cấu trúc XML hoặc cấu trúc dữ liệu Java duy nhất. Tài liệu JiBX bao gồm một hướng dẫn để minh họa nhiều khía cạnh khi làm việc với các định nghĩa liên kết, bao gồm cả các đặc tính mở rộng này, cùng với tài liệu tham khảo có tất cả các thông tin chi tiết.

JiBX đặc biệt tiện lợi khi bạn muốn phát triển một định nghĩa lược đồ một cách nhanh chóng để trao đổi dữ liệu mà không cần phải tìm hiểu nhiều về lược đồ. Lược đồ XML tiêu chuẩn là phức tạp và các công cụ để làm việc với các định nghĩa lược đồ cung cấp rất ít hỗ trợ cho việc tổ chức lại và cấu trúc lại các lược đồ. Bằng cách sử dụng mã Java và BindGen làm cơ sở cho sự phát triển lược đồ của bạn như đã chỉ ra trong hướng dẫn này, bạn có thể áp dụng tất cả tính linh hoạt của các IDE Java để tạo ra định nghĩa lược đồ một cách nhanh chóng và dễ dàng mà không phải tự cam kết sử dụng JiBX.

JiBX cũng bao gồm một công cụ để tạo ra đầy đủ các định nghĩa lược đồ và WSDL cho các dịch vụ Web dựa trên mã Java. Công cụ này, có tên Jibx2Wsdl, được xây dựng bên trên BindGen. Bạn có thể sử dụng tất cả các tuỳ chỉnh BindGen đã bàn luận trong bài viết này cho các lớp dữ liệu được sử dụng làm đầu vào và đầu ra cho các phương thức dịch vụ của bạn, sao cho lược đồ được tạo ra sẽ phản ánh sở thích của bạn. Tài liệu JiBX cung cấp các chi tiết về cách sử dụng Jibx2Wsdl như thế nào.

Trong Phần 2, bạn sẽ tìm hiểu cách sử dụng JiBX để tạo mã Java từ các định nghĩa lược đồ XML.


Tải về

Mô tảTênKích thước
mã ví dụ cho bài học nàyj-jibx1.zip13KB

Tài nguyên

Học tập

  • JiBX: Binding XML to Java Code: Truy cập vào trang web JiBX để tìm tài liệu API, tin tức về dự án và các tài nguyên khác.
  • "Classworking toolkit: Inside JiBX code generation" (Dennis Sosnoski, developerWorks, 09.2005): Tìm hiểu cách JiBX thực hiện nâng cao tệp tin lớp để liên kết dữ liệu XML như thế nào.
  • "XML and Java technologies: Data binding Part 3: JiBX architecture" và "XML and Java technologies: Data binding Part 4: JiBX Usage" (Dennis Sosnoski, developerWorks, 04.2003): Liên kết dữ liệu Phần 4: Sử dụng JiBX" (Dennis Sosnoski, developerWorks, 04.2003): Những bài viết này, dựa trên một phiên bản phát triển JiBX trước đây, thảo luận về cấu trúc bên trong của JiBX và cách làm thế nào để sử dụng nhằm liên kết linh hoạt các đối tượng Java tới XML.
  • "Transform Java classes into Web services using Axis2 and JiBX" (Tyler Anderson, developerWorks, 03.2007): Đọc bài viết hai phần này để tìm hiểu làm thế nào để sử dụng JiBX để định nghĩa một dịch vụ Web từ các lớp Java hiện có.
  • JAXB Reference Implementation: Tìm hiểu về tiêu chuẩn Java JAXB 2.0 cho việc liên kết dữ liệu XML, với gói hỗ trợ môi trường chạy Java 6 và JRE mới hơn.
  • "'Code First' Web Services Reconsidered" (Dennis Sosnoski, InfoQ, 08.2007): Tìm hiểu tại sao xây dựng dựa trên mã hiện có lại có thể là một biện pháp thực tế để bắt đầu phát triển dịch vụ trên web.
  • Data binding with Castor (Brett D. McLaughlin, developerWorks, 2007-2008): Tìm hiểu về một công cụ liên kết dữ liệu nguồn mở khác trong loạt bài viết này.
  • Duyệt qua technology bookstore Duyệt qua hiệu sách công nghệ để tìm các sách về các chủ đề kỹ thuật này và các chủ đề kỹ thuật khác.
  • developerWorks Java technology zone: Tìm hàng trăm bài viết về mọi khía cạnh của lập trình Java.

Lấy sản phẩm và công nghệ

  • JiBX: Tải về JiBX.
  • Ant: Tải về Apache Ant.
  • Sun JDK 1.5 or later: Bạn sẽ cần ít nhất là phiên bản 1.5.0_09 để thực hiện các ví dụ trong hướng dẫn này.
  • IBM® developer kits: Các bộ dụng cụ của nhà phát triển Java của IBM có sẵn cho AIX và Linux.

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Công nghệ Java, Nguồn mở
ArticleID=388577
ArticleTitle=JiBX 1.2, Phần 1: Từ mã Java thành lược đồ XML
publish-date=05202009