Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Magic with Merlin: Long-term persistence

Serialize JavaBean component state to XML

John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.
Author photo
John Zukowski conducts strategic Java consulting with JZ Ventures, Inc. and serves as the resident guru for a number of jGuru's community-driven Java FAQs. His latest books are Java Collections and Definitive Guide to Swing for Java 2 (2nd ed) from Apress. Contact John at jaz@zukowski.net.

Summary:  The ability to save the JavaBean component state for long-term persistence within an XML document has been a topic of much discussion with Java developers in the past few years. This feature has finally been adopted in the 1.4 version of J2SE. In this installment of Magic with Merlin, John Zukowski shows you how to use the new XMLEncoder and XMLDecoder classes, bypassing serialization and allowing you to generate fully initialized bean instances.

View more content in this series

Date:  01 Jul 2001
Level:  Introductory
Also available in:   Japanese

Activity:  9516 views
Comments:  

One new feature of Merlin has been thrown around in various incarnations at Sun's Swing Connection for some time now; in fact, it was first discussed at the 1999 JavaOne show. That feature is the ability to save the JavaBean component state for long-term persistence within an XML document. Serialization works fine for short-term marshaling needs, with CORBA and RMI, or for saving state information within an executing servlet. However, serialization can run into problems across versions of class libraries or Java run-time environments, among many other issues. The new XMLEncoder / XMLDecoder classes permit the dumping of the JavaBean component state to a text file for easy modification outside of a Java program or more likely for the generation of such files. Let's take a look at how to use the classes and examine the file generated.

Getting started

To get started, we need to define a class that we're going to initialize, save, and re-create. Let's define a class with four properties:

  • An integer array of test scores, treated as an indexed property
  • A read-only float property for the score average
  • A String property representing the student's name
  • A java.awt.Point property representing where the student sits in the class

This varied set of property types will demonstrate how the encoder deals with different datatypes. Listing 1 shows the sample class definition. (It's also in package net.zukowski.ibm available in Downloads.) There's even a nice little toString() method that we can use to visually see that the retrieved values are set properly.


Saving state

Now that we have a class to save, we can create an instance and use the XMLEncoder to save it. Found in the java.beans package, the class works like an ObjectOutputStream but isn't part of the OutputStream class hierarchy. You pass in the OutputStream you want to save to, and call its writeObject() method to write an object to the stream. It's that easy.

  // Create
  Sample sample = new Sample();
  sample.setScores(new int[] {100, 90, 75});
  sample.setName("Gore");
  sample.setSeat(new Point(5, 3));
  // Save
  XMLEncoder encoder = new XMLEncoder(
    new BufferedOutputStream(
      new FileOutputStream("Sample.xml")));
  encoder.writeObject(sample);
  encoder.close();


Examining the format

As you examine the XML file shown in Listing 3, you'll notice that how to read the format is encoded with the output, in this case with the XMLDecoder from the v1.4 beta. This approach provides for future releases to change the format such that if an older XML file comes around, the new decoder will know what encoding style was used when the XML file was generated. Essentially, the file is a regular XML file, following a particular DTD that is not referenced by the file. Instead, the decoder knows it.

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.0-beta" class="java.beans.XMLDecoder">
  <object class="net.zukowski.ibm.Sample">
    <void property="name">
      <string>Gore</string>
    </void>
    <void property="scores">
      <array class="int" length="3">
        <void index="0">
          <int>100</int>
        </void>
        <void index="1">
          <int>90</int>
        </void>
        <void index="2">
          <int>75</int>
        </void>
      </array>
    </void>
    <void property="seat">
      <object class="java.awt.Point">
        <int>5</int>
        <int>3</int>
      </object>
    </void>
  </object>
</java>

Not shown with this particular XML file is how to embed method calls for resetting bean properties, like adding listeners and adding components into containers.


Reading back

Reading the object graph of the original graph is as easy as saving it, but this time we use XMLDecoder. The decoder works like the ObjectInputStream, where you pass the InputStream of the file into the constructor, and read the object with the readObject() method. You still even have to cast the results to the proper type.

  // Read
  XMLDecoder decoder = new XMLDecoder(
    new BufferedInputStream(
      new FileInputStream("Sample.xml")));
  Sample sample2 = (Sample)decoder.readObject();
  decoder.close();


Complete example

Essentially, that's all there is to encoding and decoding a JavaBean component state to and from XML. There's much more going on behind the scenes here than meets the eye. However, to use the classes, you don't need to know it all, just like with serialization. If you are interested in generating the XML file yourself, you will have to read more about the file format (see Resources).

Here's the complete testing example to create an instance, encode it, and then decode it back.

import net.zukowski.ibm.Sample;
import java.io.*;
import java.beans.*;
import java.awt.Point;
public class SampleTest {
  public static void main (String args[]) throws Exception {
    Sample sample = new Sample();
    sample.setScores(new int[] {100, 90, 75});
    sample.setName("Gore");
    sample.setSeat(new Point(5, 3));
    XMLEncoder encoder = new XMLEncoder(
      new BufferedOutputStream(
        new FileOutputStream("Sample.xml")));
    encoder.writeObject(sample);
    encoder.close();
    System.out.println(sample);
    XMLDecoder decoder = new XMLDecoder(
      new BufferedInputStream(
        new FileInputStream("Sample.xml")));
    Sample sample2 = (Sample)decoder.readObject();
    decoder.close();
    System.out.println(sample2);
  }
}



Download

NameSizeDownload method
j-mer0731source.zip2 KB HTTP

Information about download methods


Resources

About the author

Author photo

John Zukowski conducts strategic Java consulting with JZ Ventures, Inc. and serves as the resident guru for a number of jGuru's community-driven Java FAQs. His latest books are Java Collections and Definitive Guide to Swing for Java 2 (2nd ed) from Apress. Contact John at jaz@zukowski.net.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10571
ArticleTitle=Magic with Merlin: Long-term persistence
publish-date=07012001
author1-email=jaz@zukowski.net
author1-email-cc=jaloi@us.ibm.com