April 18, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Web Services-Not Always the Best Solution, Page 5

  • May 28, 2009
  • By Liviu Tudor, Liviu Tudor
  • Send Email »
  • More Articles »

Communicating via Java Objects

So based on the same pattern of spawning a thread each time a client connects to our server (as used in XMLSerAddressBookServer), this section implements a JavaSerAddressBookServer. The only differences lie in reading requests and writing responses; this approach uses ObjectInput and OutputStream to read and write the requests and responses. Because the server supports only one request type (findAddress), the client must send only the name to look up, which can be done by sending a serialized String object. The server returns an AddressBean instance (which if you recall was declared as Serializable), so all the server does to reply to a request is write the AddressBean to the socket using an ObjectOutputStream. Therefore, the server implementation will look like this:

public class JavaSerAddressBookServer 
{
   public static final int SERVER_PORT = 8899;
   private AddressBook book;
   private ServerSocket srvSock;
      
   public JavaSerAddressBookServer() throws IOException
   {
      book = new AddressBook();
      srvSock = new ServerSocket( SERVER_PORT );
   }
   
   public void startListening() 
   {
      Socket s = null;
      while( true )
      {
         try
         {
            s = srvSock.accept();
            Thread t = new Thread( new WorkerThread(s) );
            t.start();
         }
         catch( IOException e )
         {
            e.printStackTrace();
         }
      }
   }
   
   public static void main(String[] args) 
   {
      try
      {
         JavaSerAddressBookServer server = new 
            JavaSerAddressBookServer();
         server.startListening();
      }
      catch( IOException e )
      {
         e.printStackTrace();
      }
   }
   class WorkerThread implements Runnable
   {
      private Socket s;
      private String name;
      
      public WorkerThread( Socket s )
      {
         this.s = s;
      }
      
      public void run()
      {
         try
         {
            processRequest( s.getInputStream() );
            
            AddressBean a = book.findFriend( name );
            sendResponse( a, s.getOutputStream() );
         }
         catch( Exception e )
         {
            e.printStackTrace();
         }
         finally
         {
            try
            {
               s.close();
            }
            catch( IOException ioe )
            {
            }
         }
      }
      
      protected void processRequest( InputStream s ) 
         throws IOException, ClassNotFoundException
      {
         ObjectInputStream ois = new ObjectInputStream( s );
         name = (String)ois.readObject();
      }
      
      protected void sendResponse(AddressBean a, OutputStream s ) 
         throws IOException
      {
         ObjectOutputStream os = new ObjectOutputStream( s );
         os.writeObject( a );
      }
   }
   
}

The client is based on a pattern similar to the one used previously that sent XML messages over TCP/IP:

public class JavaSerAddressBookClient extends SimpleMeasurementImpl implements AddressBookContract
{
   @Override
   public AddressBean findFriend(String name) 
   {
      timeStart = System.nanoTime();
      Socket s = null;
      try
      {
         s = new Socket( "localhost", 
            JavaSerAddressBookServer.SERVER_PORT );
         sendRequest( name, s.getOutputStream() );
         AddressBean a = parseResponse( s.getInputStream() );
         return a;
      }
      catch( Exception e )
      {
         e.printStackTrace();
         return null;
      }
      finally
      {
         try
         {
            s.close();
         }
         catch(Exception e){}
         timeEnd = System.nanoTime();
      }
   }
   
   protected void sendRequest(String name, OutputStream o) 
      throws IOException
   {
      ObjectOutputStream os = new ObjectOutputStream( o );
      os.writeObject( name );
   }
   
   protected AddressBean parseResponse( InputStream s ) 
      throws IOException, ClassNotFoundException
   {
      ObjectInputStream os = new ObjectInputStream( s );
      return (AddressBean)os.readObject();
   }
}

Running the server and the client renders this output:

class javaser.JavaSerAddressBookClient found 
   Liv : Oxford Street , London , SW1 in 73,613,300

You may be surprised to find out that while this is definitely faster than the XML + TCP/IP solution (about 8 times faster), it is still considerably slower than the RMI-based solution. The reason lies in a combination of the fact that this solution must spend some time preparing the socket connection (the RMI example does that in the constructor, so everything is ready when it makes the call to the RMI server), and the way object streams deserialize objects received over the wire.

Nevertheless, note that the solution doesn't require writing any SAX parsing or XML-assembling code—and the JVM does input validation automatically. Ultimately, this solution involves writing less code and still provides a faster result.





Page 5 of 6



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel