Woodstox sample: Typed Access API, binary

Message format

Here is the simple xml message format we will be using:

<files>
  <file name="test.jpg" checksumType="SHA">... base64 encoded content ...
  </file>
  <checksum value="...base64 encoded hash of content..." />
  <!-- ... and more files (with checksums), if need be... -->
</files> 

That is, a single message contains one or more files, each with associated checksum. Checksum is used to verify that contents were passed unmodified (as opposed to being corrupted by transfer).

Client implementation

   1 import java.io.*;
   2 import java.net.URL;
   3 import java.net.URLConnection;
   4 import java.security.MessageDigest;
   5 import java.util.*;
   6 import javax.xml.stream.*;
   7 
   8 import org.codehaus.stax2.XMLStreamReader2;
   9 
  10 /// Simple example of a client that downloads a set of files from a server.
  11 public class BinaryClient
  12 {
  13     final XMLInputFactory _xmlInputFactory = XMLInputFactory.newInstance();
  14 
  15     /**
  16      * @param urlStr Full URL (including query parameters if any)
  17      *   used to access web service for downloading files.
  18      */
  19     public List<File> fetchFiles(URL serviceURL) throws Exception
  20     {
  21         List<File> files = new ArrayList<File>();
  22         URLConnection conn = serviceURL.openConnection();
  23         conn.setDoOutput(false); // only true when POSTing
  24         conn.connect();
  25         // note, should check 'if (conn.getResponseCode() != 200) ...'
  26         
  27         // Ok, let's read it then... (note: StaxMate could simplify a lot!)
  28         InputStream in = conn.getInputStream();
  29         XMLStreamReader2 sr = (XMLStreamReader2) _xmlInputFactory.createXMLStreamReader(in);
  30         sr.nextTag(); // to "files"
  31         File dir = new File("/tmp"); // for linux...
  32         byte[] buffer = new byte[4000];
  33         
  34         while (sr.nextTag() != XMLStreamConstants.END_ELEMENT) { // one more 'file'
  35             String filename = sr.getAttributeValue("", "name");
  36             String csumType = sr.getAttributeValue("", "checksumType");
  37             File outputFile = new File(dir, filename);
  38             FileOutputStream out = new FileOutputStream(outputFile);
  39             files.add(outputFile);
  40             MessageDigest md = MessageDigest.getInstance(csumType);
  41             
  42             int count;
  43             // Read binary contents of the file, calc checksum and write
  44             while ((count = sr.readElementAsBinary(buffer, 0, buffer.length)) != -1) {
  45                 md.update(buffer, 0, count);
  46                 out.write(buffer, 0, count);
  47             }
  48             out.close();
  49             // Then verify checksum
  50             sr.nextTag();  
  51             byte[] expectedCsum = sr.getAttributeAsBinary(sr.getAttributeIndex("", "value"));
  52             byte[] actualCsum = md.digest();
  53             if (!Arrays.equals(expectedCsum, actualCsum)) {
  54                 throw new IllegalArgumentException("File '"+filename+"' corrupt: content checksum does not match expected");
  55             }
  56             sr.nextTag(); // to match closing "checksum"
  57         }
  58         return files;
  59     }
  60 
  61     // Call with arg like "localhost:8080/downloadServlet"
  62     public static void main(String[] args) throws Exception {
  63         if (args.length != 1) {
  64             System.err.println("Usage: java BinaryClient [URL]");
  65             System.exit(1);
  66         }
  67         URL serviceURL = new URL(args[0]);
  68         System.out.println("Fetching files from '"+serviceURL.toExternalForm()+"'...");
  69         List<File> files = new BinaryClient().fetchFiles(serviceURL);
  70         System.out.println("OK: Fetched "+files.size()+" files with correct checksums:");
  71         for (File f : files) {
  72             System.out.println(" File '"+f.getAbsolutePath()+"'");
  73         }
  74         System.out.println("Done.");
  75     }
  76 }

Service implementation

   1 // TO BE WRITTEN

Authoritative source code

The original source code is included with Woodstox distribution, and is stored in Woodstox SVN Repository under src/samples (files BinaryService.java and BinaryClient.java.


CategoryWoodstox

WoodstoxSampleBinaryService (last edited 2009-09-09 06:30:08 by TatuSaloranta)

Copyright ©2009 FasterXML, LLC