A WebRowSet object is very special because in addition to offering all of the capabilities of a CachedRowSet object, it can write itself as an XML document and can also read that XML document to convert itself back to a WebRowSet object. Because XML is the language through which disparate enterprises can communicate with each other, it has become the standard for Web Services communication. As a consequence, a WebRowSet object fills a real need by enabling Web Services to send and receive data from a database in the form of an XML document.
    
The following topics are covered:
The Coffee Break company
      has expanded to selling coffee online. Users order coffee
      by the pound from the Coffee Break Web site. The price list
      is regularly updated by getting the latest information from
      the company's database. This section demonstrates how to send the price data as an XML document with a WebRowSet object and a single method call.
    
      You create a new WebRowSet object with the default
      constructor defined in the reference implementation,
      WebRowSetImpl, as shown in the following line of code:
    
WebRowSet priceList = new WebRowSetImpl();
      Although the priceList object has no data yet, it has the default properties of a BaseRowSet object. Its SyncProvider
      object is at first set to the RIOptimisticProvider
      implementation, which is the default for all disconnected
      RowSet objects. However, the WebRowSet implementation
      resets the SyncProvider object to be the RIXMLProvider
      implementation.
You can use an instance of RowSetFactory, which is created from the RowSetProvider class, to create a WebRowSet object. See Using the RowSetFactory Interface in Using JdbcRowSet Objects for more information.
The Coffee Break headquarters
      regularly sends price list updates to its web site. This information on WebRowSet objects will show one way you can send the latest price list in an XML document. 
      The price list consists of the data in the columns COF_NAME
      and PRICE from the table COFFEES. The following code
      fragment sets the properties needed and populates
      the priceList object with the price list data:
    
public void getPriceList(String username, String password) {
  priceList.setCommand("SELECT COF_NAME, PRICE FROM COFFEES");
  priceList.setURL("jdbc:mySubprotocol:myDatabase");
  priceList.setUsername(username);
  priceList.setPassword(password);
  priceList.execute();
  // ...
      At this point, in addition to the default properties,
      the priceList object contains the data in the COF_NAME
      and PRICE columns from the COFFEES table and also the metadata
      about these two columns.
    
      To write a WebRowSet object as an XML document,  call the method writeXml. To read that XML document's contents into a WebRowSet
      object, call the method readXml. Both of these methods
      do their work in the background, meaning that everything,
      except the results, is invisible to you.
    
      The method writeXML writes the WebRowSet object that
      invoked it as an XML document that represents its current
      state. It writes this XML document to the stream that you
      pass to it. The stream can be an OutputStream object, such
      as a FileOutputStream object, or a Writer object, such as
      a FileWriter object. If you pass the method writeXML an
      OutputStream object, you will write in bytes, which can
      handle all types of data; if you pass it a Writer object,
      you will write in characters. The following code
      demonstrates writing the WebRowSet object priceList
      as an XML document to the FileOutputStream object
      oStream:
    
java.io.FileOutputStream oStream = new java.io.FileOutputStream("priceList.xml");
priceList.writeXml(oStream);
      The following code writes the XML document representing
      priceList to the FileWriter object writer
      instead of to an OutputStream object. The FileWriter class
      is a convenience class for writing characters to a file.
java.io.FileWriter writer = new java.io.FileWriter("priceList.xml");
priceList.writeXml(writer);
      The other two versions of the method writeXML let you
      populate a WebRowSet object with the contents of a
      ResultSet object before writing it to a stream. In the
      following line of code, the method writeXML reads the
      contents of the ResultSet object rs into
      the priceList object and then writes priceList to the
      FileOutputStream object oStream as an XML document.
    
priceList.writeXml(rs, oStream);
      In the next line of code, the writeXML methodpopulates
      priceList with the contents of rs, but it
      writes the XML document to a FileWriter object instead of
      to an OutputStream object:
    
priceList.writeXml(rs, writer);
      The method readXml parses an XML document in order to
      construct the WebRowSet object the XML document describes.
      Similar to the method writeXml, you can pass readXml an
      InputStream object or a Reader object from which to read
      the XML document.
    
java.io.FileInputStream iStream = new java.io.FileInputStream("priceList.xml");
priceList.readXml(iStream);
java.io.FileReader reader = new
java.io.FileReader("priceList.xml");
priceList.readXml(reader);
Note that you can read the XML description into a new
      WebRowSet object or into the same WebRowSet object that
      called the writeXML method. In the scenario, where the
      price list information is being sent from headquarters to
      the Web site, you would use a new WebRowSet object, as
      shown in the following lines of code:
WebRowSet recipient = new WebRowSetImpl();
java.io.FileReader reader = new java.io.FileReader("priceList.xml");
recipient.readXml(reader);
      RowSet objects are more than just the data they contain.
      They have properties and metadata about their columns as
      well. Therefore, an XML document representing a WebRowSet
      object includes this other information in addition to its
      data. Further, the data in an XML document includes both
      current values and original values. (Recall that original values are the values
      that existed immediately before the most recent changes to
      data were made. These values are necessary for checking
      if the corresponding value in the database has been
      changed, thus creating a conflict over which value should
      be persistent: the new value you put in the RowSet object or
      the new value someone else put in the database.)
    
      The WebRowSet XML Schema, itself an XML document, defines
      what an XML document representing a WebRowSet object will
      contain and also the format in which it must be presented.
      Both the sender and the recipient use this schema because
      it tells the sender how to write the XML document (which represents the WebRowSet object) and the recipient
      how to parse the XML document. Because the actual writing and
      reading is done internally by the implementations of the
      methods writeXML and readXml, you, as a user, do not need
      to understand what is in the WebRowSet XML Schema
      document.
    
      XML documents contain elements and subelements in a
      hierarchical structure. The following are the three main
      elements in an XML document describing a WebRowSet object:
    
      Element tags signal the beginning and end of an element.
      For example, the <properties> tag signals the beginning of
      the properties element, and the </properties> tag signals its
      end. The <map/> tag is a shorthand way of saying that the map
      subelement (one of the subelements in the properties
      element) has not been assigned a value. The following sample XML documents uses spacing and indentation to make it easier
      to read, but those are not used in an actual XML document,
      where spacing does not mean anything.
    
      The next three sections show you what the three main
      elements contain for the WebRowSet priceList object,
      created in the sample WebRowSetSample.java.
      Calling the method writeXML on the priceList object would
      produce an XML document describing priceList. The
      properties section of this XML document would look like the
      following:
    
  <properties>
    <command>select COF_NAME, PRICE from COFFEES</command>
    <concurrency>1008</concurrency>
    <datasource><null/></datasource>
    <escape-processing>true</escape-processing>
    <fetch-direction>1000</fetch-direction>
    <fetch-size>0</fetch-size>
    <isolation-level>2</isolation-level>
    <key-columns>
      <column>1</column>
    </key-columns>
    <map>
    </map>
    <max-field-size>0</max-field-size>
    <max-rows>0</max-rows>
    <query-timeout>0</query-timeout>
    <read-only>true</read-only>
    <rowset-type>ResultSet.TYPE_SCROLL_INSENSITIVE</rowset-type>
    <show-deleted>false</show-deleted>
    <table-name>COFFEES</table-name>
    <url>jdbc:mysql://localhost:3306/testdb</url>
    <sync-provider>
      <sync-provider-name>com.sun.rowset.providers.RIOptimisticProvider</sync-provider-name>
      <sync-provider-vendor>Sun Microsystems Inc.</sync-provider-vendor>
      <sync-provider-version>1.0</sync-provider-version>
      <sync-provider-grade>2</sync-provider-grade>
      <data-source-lock>1</data-source-lock>
    </sync-provider>
  </properties>
      Notice that some properties have no value. For
      example, the datasource property is indicated with
      the <datasource/> tag, which is a shorthand way of saying
      <datasource></datasource>. No value is given
      because the url property is set. Any connections that are
      established will be done using this JDBC URL, so no
      DataSource object needs to be set. Also, the username and
      password properties are not listed because they must
      remain secret.
    
      The metadata section of the XML document describing a
      WebRowSet object contains information about the columns in
      that WebRowSet object. The following shows what this
      section looks like for the WebRowSet object
      priceList. Because the priceList object has two columns,
      the XML document describing it has two
      <column-definition> elements. Each
      <column-definition> element has subelements giving
      information about the column being described.
    
  <metadata>
    <column-count>2</column-count>
    <column-definition>
      <column-index>1</column-index>
      <auto-increment>false</auto-increment>
      <case-sensitive>false</case-sensitive>
      <currency>false</currency>
      <nullable>0</nullable>
      <signed>false</signed>
      <searchable>true</searchable>
      <column-display-size>32</column-display-size>
      <column-label>COF_NAME</column-label>
      <column-name>COF_NAME</column-name>
      <schema-name></schema-name>
      <column-precision>32</column-precision>
      <column-scale>0</column-scale>
      <table-name>coffees</table-name>
      <catalog-name>testdb</catalog-name>
      <column-type>12</column-type>
      <column-type-name>VARCHAR</column-type-name>
    </column-definition>
    <column-definition>
      <column-index>2</column-index>
      <auto-increment>false</auto-increment>
      <case-sensitive>true</case-sensitive>
      <currency>false</currency>
      <nullable>0</nullable>
      <signed>true</signed>
      <searchable>true</searchable>
      <column-display-size>12</column-display-size>
      <column-label>PRICE</column-label>
      <column-name>PRICE</column-name>
      <schema-name></schema-name>
      <column-precision>10</column-precision>
      <column-scale>2</column-scale>
      <table-name>coffees</table-name>
      <catalog-name>testdb</catalog-name>
      <column-type>3</column-type>
      <column-type-name>DECIMAL</column-type-name>
    </column-definition>
  </metadata>
      From this metadata section, you can see that there are two
      columns in each row. The first column is COF_NAME, which
      holds values of type VARCHAR. The second column is PRICE,
      which holds values of type REAL, and so on. Note that the
      column types are the data types used in the data source,
      not types in the Java programming language. To get or
      update values in the COF_NAME column, you use the methods getString or
      updateString, and the driver makes the conversion to
      the VARCHAR type, as it usually does.
    
      The data section gives the values for each column in each
      row of a WebRowSet object. If you have populated
      the priceList object and not made any changes to it, the data
      element of the XML document will look like the following.
      In the next section you will see how the XML document
      changes when you modify the data in the priceList object.
    
      For each row there is a <currentRow> element, and
      because priceList has two columns, each
      <currentRow> element contains two <columnValue>
      elements.
    
  <data>
    <currentRow>
      <columnValue>Colombian</columnValue>
      <columnValue>7.99</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>Colombian_Decaf</columnValue>
      <columnValue>8.99</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>Espresso</columnValue>
      <columnValue>9.99</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>French_Roast</columnValue>
      <columnValue>8.99</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>French_Roast_Decaf</columnValue>
      <columnValue>9.99</columnValue>
    </currentRow>
  </data>
      You make changes to a WebRowSet object the same way you do
      to a CachedRowSet object. Unlike a CachedRowSet object,
      however, a WebRowSet object keeps track of updates,
      insertions, and deletions so that the writeXML method can
      write both the current values and the original values. The
      three sections that follow demonstrate making changes to
      the data and show what the XML document describing the
      WebRowSet object looks like after each change. You do not
      have to do anything at all regarding the XML document; any
      change to it is made automatically, just
      as with writing and reading the XML document.
    
If the owner of the Coffee Break chain wants to add a new coffee to the price list, the code might look like this:
priceList.absolute(3);
    priceList.moveToInsertRow();
priceList.updateString(COF_NAME, "Kona");
priceList.updateFloat(PRICE, 8.99f);
priceList.insertRow();
priceList.moveToCurrentRow();
      In the reference implementation, an insertion is made
      immediately following the current row. In the preceding
      code fragment, the current row is the third row, so the new
      row would be added after the third row and become the new
      fourth row. To reflect this insertion, the XML document
      would have the following <insertRow> element added to
      it after the third <currentRow> element in the
      <data> element.
    
      The <insertRow> element will look similar to the
      following.
    
    <insertRow>
      <columnValue>Kona</columnValue>
      <columnValue>8.99</columnValue>
    </insertRow>
      The owner decides that Espresso is not selling enough and
      should be removed from the coffees sold at The Coffee
      Break shops. The owner therefore wants to delete Espresso from the price
      list. Espresso is in the third row of the priceList object, so
      the following lines of code delete it:
priceList.absolute(3); priceList.deleteRow();
      The following <deleteRow> element will appear after
      the second row in the data section of the XML document,
      indicating that the third row has been deleted.
    
    <deleteRow>
      <columnValue>Espresso</columnValue>
      <columnValue>9.99</columnValue>
    </deleteRow>
The owner further decides that the price of Colombian coffee is too expensive and wants to lower it to .99 a pound. The following code sets the new price for Colombian coffee, which is in the first row, to .99 a pound:
priceList.first(); priceList.updateFloat(PRICE, 6.99);
      The XML document will reflect this change in an
      <updateRow> element that gives the new value. The value for
      the first column did not change, so there is an
      <updateValue> element only for the second column:
    <currentRow>
      <columnValue>Colombian</columnValue>
      <columnValue>7.99</columnValue>
      <updateRow>6.99</updateRow>
    </currentRow>
      At this point, with the insertion of a row, the deletion of
      a row, and the modification of a row, the XML document for
      the priceList object would look like the following:
    
  <data>
    <insertRow>
      <columnValue>Kona</columnValue>
      <columnValue>8.99</columnValue>
    </insertRow>
    <currentRow>
      <columnValue>Colombian</columnValue>
      <columnValue>7.99</columnValue>
      <updateRow>6.99</updateRow>
    </currentRow>
    <currentRow>
      <columnValue>Colombian_Decaf</columnValue>
      <columnValue>8.99</columnValue>
    </currentRow>
    <deleteRow>
      <columnValue>Espresso</columnValue>
      <columnValue>9.99</columnValue>
    </deleteRow>
    <currentRow>
      <columnValue>French_Roast</columnValue>
      <columnValue>8.99</columnValue>
    </currentRow>
    <currentRow>
      <columnValue>French_Roast_Decaf</columnValue>
      <columnValue>9.99</columnValue>
    </currentRow>
  </data>
The sample WebRowSetSample.java demonstrates all the features described on this page.