In the preceding examples, you learned how to send and receive data of primitive types. You can also send and receive objects using ObjectOutputStream and ObjectInputStream on socket streams. To enable passing, the objects must be serializable. The following example demonstrates how to send and receive objects.
The example consists of three classes: Student.java (Listing 25.7), StudentClient.java (Listing 25.8), and StudentServer.java (Listing 25.9). The client program collects student information from a client and sends it to a server, as shown in Figure 25.10.
The Student class contains the student information: name , street, state, and zip. The Student class implements the Serializable interface. Therefore, it can be sent and received using the object output and input streams.
1 public class Student implements java.io.Serializable { 2 private String name; 3 private String street; 4 private String city; 5 private String state; 6 private String zip; 7 8 public Student(String name, String street, String city, 9 String state, String zip) { 10 this .name = name; 11 this .street = street; 12 this .city = city; 13 this .state = state; 14 this .zip = zip; 15 } 16 17 public String getName() { 18 return name; 19 } 20 21 public String getStreet() { 22 return street; 23 } 24 25 public String getCity() { 26 return city; 27 } 28 29 public String getState() { 30 return state; 31 } 32 33 public String getZip() { 34 return zip; 35 } 36 } |
The client sends a Student object through an ObjectOutputStream on the output stream socket, and the server receives the Student object through the ObjectInputStream on the input stream socket, as shown in Figure 25.11. The client uses the writeObject method in the ObjectOutputStream class to send a student to the server, and the server receives the student using the readObject method in the ObjectInputStream class. The server and client programs are given in Listings 25.8 and 25.9.
1 import java.io.*; 2 import java.net.*; 3 import java.awt.*; 4 import java.awt.event.*; 5 import javax.swing.*; 6 import javax.swing.border.*; 7 8 public class StudentClient extends JApplet { 9 private JTextField jtfName = new JTextField( 32 ); 10 private JTextField jtfStreet = new JTextField( 32 ); 11 private JTextField jtfCity = new JTextField( 20 ); 12 private JTextField jtfState = new JTextField( 2 ); 13 private JTextField jtfZip = new JTextField( 5 ); 14 15 // Button for sending a student to the server 16 private JButton jbtRegister = new JButton( "Register to the Server" ); 17 18 // Indicate if it runs as application 19 private boolean isStandAlone = false ; 20 21 // Host name or ip 22 String host = "localhost" ; 23 24 public void init() { 25 // Panel p1 for holding labels Name, Street, and City 26 JPanel p1 = new JPanel(); 27 p1.setLayout( new GridLayout( 3 , 1 )); 28 p1.add( new JLabel( "Name" )); 29 p1.add( new JLabel( "Street" )); 30 p1.add( new JLabel( "City" )); 31 32 // Panel jpState for holding state 33 JPanel jpState = new JPanel(); 34 jpState.setLayout( new BorderLayout()); 35 jpState.add( new JLabel( "State" ), BorderLayout.WEST); 36 jpState.add(jtfState, BorderLayout.CENTER); 37 38 // Panel jpZip for holding zip 39 JPanel jpZip = new JPanel(); 40 jpZip.setLayout( new BorderLayout()); 41 jpZip.add( new JLabel( "Zip" ), BorderLayout.WEST); 42 jpZip.add(jtfZip, BorderLayout.CENTER); 43 44 // Panel p2 for holding jpState and jpZip 45 JPanel p2 = new JPanel(); 46 p2.setLayout( new BorderLayout()); 47 p2.add(jpState, BorderLayout.WEST); 48 p2.add(jpZip, BorderLayout.CENTER); 49 50 // Panel p3 for holding jtfCity and p2 51 JPanel p3 = new JPanel(); 52 p3.setLayout( new BorderLayout()); 53 p3.add(jtfCity, BorderLayout.CENTER); 54 p3.add(p2, BorderLayout.EAST); 55 56 // Panel p4 for holding jtfName, jtfStreet, and p3 57 JPanel p4 = new JPanel(); 58 p4.setLayout( new GridLayout( 3 , 1 )); 59 p4.add(jtfName); 60 p4.add(jtfStreet); 61 p4.add(p3); 62 63 // Place p1 and p4 into StudentPanel 64 JPanel studentPanel = new JPanel( new BorderLayout()); 65 studentPanel.setBorder( new BevelBorder(BevelBorder.RAISED)); 66 studentPanel.add(p1, BorderLayout.WEST); 67 studentPanel.add(p4, BorderLayout.CENTER); 68 69 // Add the student panel and button to the applet 70 add(studentPanel, BorderLayout.CENTER); 71 add(jbtRegister, BorderLayout.SOUTH); 72 73 // Register listener 74 jbtRegister.addActionListener( new ButtonListener()); 75 76 // Find the IP address of the Web server 77 if (!isStandAlone) 78 host = getCodeBase().getHost(); 79 } 80 81 /** Handle button action */ 82 private class ButtonListener implements ActionListener { 83 public void actionPerformed(ActionEvent e) { 84 try { 85 // Establish connection with the server 86 Socket socket = new Socket(host, 8000 ); 87 88 // Create an output stream to the server 89 ObjectOutputStream toServer = 90 new ObjectOutputStream(socket.getOutputStream()); 91 92 // Get text field 93 String name = jtfName.getText().trim(); 94 String street = jtfStreet.getText().trim(); 95 String city = jtfCity.getText().trim(); 96 String state = jtfState.getText().trim(); 97 String zip = jtfZip.getText().trim(); 98 99 // Create a Student object and send to the server 100 Student s = new Student(name, street, city, state, zip); 101 toServer.writeObject(s); 102 } 103 catch (IOException ex) { 104 System.err.println(ex); 105 } 106 } 107 } 108 109 /** Run the applet as an application */ 110 public static void main(String[] args) { 111 // Create a frame 112 JFrame frame = new JFrame( "Register Student Client" ); 113 114 // Create an instance of the applet 115 StudentClient applet = new StudentClient(); 116 applet.isStandAlone = true ; 117 118 // Get host 119 if (args.length == 1 ) applet.host = args[ ]; 120 121 // Add the applet instance to the frame 122 frame.add(applet, BorderLayout.CENTER); 123 124 // Invoke init() and start() 125 applet.init(); 126 applet.start(); 127 128 // Display the frame 129 frame.pack(); 130 frame.setVisible( true ); 131 } 132 } |
1 import java.io.*; 2 import java.net.*; 3 4 public class StudentServer { 5 private ObjectOutputStream outputToFile; 6 private ObjectInputStream inputFromClient; 7 8 public static void main(String[] args) { 9 new StudentServer(); 10 } 11 12 public StudentServer() { 13 try { 14 // Create a server socket 15 ServerSocket serverSocket = new ServerSocket( 8000 ); 16 System.out.println( "Server started " ); 17 18 // Create an object ouput stream 19 outputToFile = new ObjectOutputStream( 20 new FileOutputStream( "student.dat" , true )); 21 22 while ( true ) { 23 // Listen for a new connection request 24 Socket socket = serverSocket.accept(); 25 26 // Create an input stream from the socket 27 inputFromClient = 28 new ObjectInputStream(socket.getInputStream()); 29 30 // Read from input 31 Object object = inputFromClient.readObject() ; 32 33 // Write to the file 34 outputToFile.writeObject(object); 35 System.out.println( "A new student object is stored" ); 36 } 37 } 38 catch (ClassNotFoundException ex) { 39 ex.printStackTrace(); 40 } 41 catch (IOException ex) { 42 ex.printStackTrace(); 43 } 44 finally { 45 try { 46 inputFromClient.close(); 47 outputToFile.close(); 48 } 49 catch (Exception ex) { 50 ex.printStackTrace(); 51 } 52 } 53 } 54 } |
On the client side, when the user clicks the "Register to the Server" button, the client creates a socket to connect to the host (line 86), creates an ObjectOutputStream on the output stream of the socket (lines 89 “90), and invokes the writeObject method to send the Student object to the server through the object output stream (line 101).
On the server side, when a client connects to the server, the server creates a thread to process the client registration (line 24). The thread creates an ObjectInputStream on the input stream of the socket (lines 27 “28), invokes the readObject method to receive the Student object through the object input stream (line 31), and writes the object to a file (line 34).
This program can run either as an applet or as an application. To run it as an application, the host name is passed as a command-line argument.