1 / 50

Servlets Chapter 10

Servlets Chapter 10. Applet/servlet communication (with a database twist). Why would you want applet-servlet communication?. At the time the text was written, jsp had not established itself as THE way to do UI. (It still hasn’t but that’s another story).

Download Presentation

Servlets Chapter 10

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Servlets Chapter 10 Applet/servlet communication (with a database twist)

  2. Why would you want applet-servlet communication? • At the time the text was written, jsp had not established itself as THE way to do UI. (It still hasn’t but that’s another story). • Flex wasn’t around yet as a presentation option. • The java api is big and you can build nice UI with it, although it is not always quick or easy.

  3. What is involved in applet-servlet communication? • The original applet specification prohibited applets from modifying files on the client’s machine, basically treating the applet as “untrusted”. • Later specifications allowed for “trusted” applets, making possible an applet to configure Java Web Server, or an applet to provide UI for a Blog/Chat. • Typically, an “untrusted” applet would need to communicate with the server to present information in a nice format, to the user.

  4. Why the need for applet-servlet communication? • An applet handling chat, or providing dow-jones info would need to communicate with the server for updates.

  5. Before JDK1.1 • Establish http connection to CGI program on server. The applet acts like a browser. • Have applet establish a raw socket connection to a non-http server. This program would listen on some port and communicate using a custom protocol.

  6. Choice 1: pros • Choice 1 is easy to write. Applet can use java.net.URL and .URLConnection classes to manage the channel, and the CGI program can be written as usual. • Even if the applet is behind a firewall it should work. (Firewalls typically allow http connections but disallow raw sockets). • The server-side programming can be done in any language. • It works for jdk1.0 and so works for all java-enabled browsers. • Using https, it would be possible to establish a secure connection. • The same CGI program could be accessed by browsers as well.

  7. Choice 1: cons • It is slow. The two programs can’t communicate interactively. There’s also a delay when the CGI launches. • Requests are typically an array of name/value pairs. • Responses must be formatted in a previously devised manner. • Only the applet can initiate the communication.

  8. Choice 2 pros & cons • Allows bi-directional sustained communication. • The server-side program can be more efficient. • BUT • It fails if the applet is behind a firewall. • The server-side code may be complicated to write. Some process must be listening at a port. • A custom protocol may need to be developed. • The server-side program probably can’t be used by browers.

  9. Servlets and object serialization • Servlets have made much headway replacing slow CGI programs. • Java object serialization simplifies the applet-servlet communication model. • A dedicated communication “object” can be passed back and forth.

  10. JDBC, CORBA, RMI • Jdk1.1 added jdbc and rmi to the java api. • In theory, an applet could use jdbc to directly connect to a database server, although in general, going through a servlet is better. To look up something in the database, an applet might pass information to a servlet which connects to the db and then passes back an object (which might just be a string.)

  11. RMI • Remote method invocation allows an applet to invoke methods of a java object on a server and possibly allows that server object to invoke applet methods, too. • It allows applets and server objects to communicate using a high-level o-o paradigm. • With RMI there is no “request” or “response” – those are http terms. Instead, there are method invokations. An applet might get a stock’s daily high by calling stockserver.dailyhigh(…) • The server can make “call backs” to methods of an applet, maybe indicating a stock price has changed by calling theapplet.update(…) • It can work through a firewall using a technique called tunneling (a non-trivial activity, or RMI could use the HTTP protocol.) HTTP does not support call-backs and has other overhead cost. RMI

  12. RMI • RMI uses “stubs” and “skeleton” classes, because the caller needs to know something about the way the callee looks, works and is called. • RMI uses a naming registry so clients can obtain references to remote objects. • Netscape $.X and up supported RMI (I think Firefox does but haven’t tried it) IE does not support RMI. • RMI requires a java client.

  13. CORBA • Common-object-request-broker-architecture is similar to RMI. • It allows for distributed objects written in different languages. • With CORBA and IIOP communication, a C++ client might communicate with a servlet. This is not covered in the Hunter text.

  14. Hunter’s chapter 10 example(s) • Hunter develops an applet/servlet that use All-of-the-above (as available) for communication. Ie., try RMI, if not supported by the browser, try a socket, but if the applet is behind a firewall, try HTTP. • Hunter’s example is the Daytime Server. It sends time of day. The applet has a GUI in which the time, retrieved via different mechanisms from the servlet, is displayed. • Some methods used are deprecated. • I don’t remember if I tried this in Netscape at the time I built it, but I would have to revisit it to see if it works in Firefox. (See next screen where RMI does NOT come up in IE).

  15. Applet called

  16. The applet slide#1 import java.io.*; import java.net.*; import java.rmi.*; import java.rmi.registry.*; import java.util.*; import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.oreilly.servlet.HttpMessage; public class DaytimeApplet extends JApplet implements ActionListener{ static final int DEFAULT_PORT = 1313; TextField httpText, httpObject, socketText, socketObject, RMIObject; Button refresh; public void init() { // Construct the user interface Container c=getContentPane(); c.setLayout(new BorderLayout()); // On the left create labels for the various communication // mechanisms Panel west = new Panel(); west.setLayout(new GridLayout(5, 1)); west.add(new Label("HTTP text: ", Label.RIGHT)); west.add(new Label("HTTP object: ", Label.RIGHT)); west.add(new Label("Socket text: ", Label.RIGHT)); west.add(new Label("Socket object: ", Label.RIGHT)); west.add(new Label("RMI object: ", Label.RIGHT)); c.add("West", west);

  17. Applet slide 2 // On the right create text fields to display the retrieved time values Panel center = new Panel(); center.setLayout(new GridLayout(5, 1)); httpText = new TextField(); httpText.setEditable(false); center.add(httpText); httpObject = new TextField(); httpObject.setEditable(false); center.add(httpObject); socketText = new TextField(); socketText.setEditable(false); center.add(socketText); socketObject = new TextField(); socketObject.setEditable(false); center.add(socketObject); RMIObject = new TextField(); RMIObject.setEditable(false); center.add(RMIObject); c.add("Center", center); // On the bottom create a button to update the times Panel south = new Panel(); refresh = new Button("Refresh"); south.add(refresh); c.add("South", south); refresh(); refresh.addActionListener(this); }

  18. Applet slide 3 private void refresh() { // Fetch and display the time values httpText.setText(getDateUsingHttpText()); httpObject.setText(getDateUsingHttpObject()); // socketText.setText(getDateUsingSocketText()); // socketObject.setText(getDateUsingSocketObject()); // RMIObject.setText(getDateUsingRMIObject()); } private String getDateUsingHttpText() { try { // Construct a URL referring to the servlet URL url = new URL( "http://CSCI345.oneonta.edu:8080/myexamples/DaytimeServlet"); // Create a com.oreilly.servlet.HttpMessage to communicate with that URL HttpMessage msg = new HttpMessage(url); // Send a GET message to the servlet, with no query string // Get the response as an InputStream InputStream in = msg.sendGetMessage(); // Wrap the InputStream with a DataInputStream DataInputStream result = new DataInputStream(new BufferedInputStream(in)); // Read the first line of the response, which should be // a string representation of the current time String date = result.readLine(); // Close the InputStream in.close(); // Return the retrieved time return date; } catch (Exception e) { // If there was a problem, print to System.out // (typically the Java console) and return null e.printStackTrace(); return null; } }

  19. Applet slide 4 private String getDateUsingHttpObject() { try { // Construct a URL referring to the servlet URL url = new URL( "http://CSCI345.oneonta.edu:8080/myexamples/DaytimeServlet"); // Create a com.oreilly.servlet.HttpMessage to communicate with that URL HttpMessage msg = new HttpMessage(url); // Construct a Properties list to say format=object Properties props = new Properties(); props.put("format", "object"); // Send a GET message to the servlet, passing "props" as a query string // Get the response as an ObjectInputStream InputStream in = msg.sendGetMessage(props); ObjectInputStream result = new ObjectInputStream(in); // Read the Date object from the stream Object obj = result.readObject(); Date date = (Date)obj; // Return the string representation of the Date return date.toString(); } catch (Exception e) { // If there was a problem, print to System.out // (typically the Java console) and return null e.printStackTrace(); return null; } }

  20. Applet slide 5 private int getSocketPort() { try { return Integer.parseInt(getParameter("socketPort")); } catch (NumberFormatException e) { return DEFAULT_PORT; } } private String getDateUsingSocketText() { InputStream in = null; try { // Establish a socket connection with the servlet Socket socket = new Socket(getCodeBase().getHost(), getSocketPort()); // Print an empty line, indicating we want the time as plain text PrintStream out = new PrintStream(socket.getOutputStream()); out.println(); out.flush(); // Read the first line of the response // It should contain the current time in = socket.getInputStream(); DataInputStream result = new DataInputStream(new BufferedInputStream(in)); String date = result.readLine(); // Return the retrieved string return date; } catch (Exception e) { // If there was a problem, print to System.out // (typically the Java console) and return null e.printStackTrace(); return null; } finally { // Always close the connection // This code executes no matter how the try block completes if (in != null) { try { in.close(); } catch (IOException ignored) { } } } }

  21. Applet slide6 private String getDateUsingSocketObject() { InputStream in = null; try { // Establish a socket connection with the servlet Socket socket = new Socket(getCodeBase().getHost(), getSocketPort()); // Print a line saying "object", indicating we want the time as // a serialized Date object PrintStream out = new PrintStream(socket.getOutputStream()); out.println("object"); out.flush(); // Create an ObjectInputStream to read the response in = socket.getInputStream(); ObjectInputStream result = new ObjectInputStream(new BufferedInputStream(in)); // Read an object, and cast it to be a Date Object obj = result.readObject(); Date date = (Date)obj; // Return a string representation of the retrieved Date return date.toString(); } catch (Exception e) { // If there was a problem, print to System.out // (typically the Java console) and return null e.printStackTrace(); return null; } finally { // Always close the connection // This code executes no matter how the try block completes if (in != null) { try { in.close(); } catch (IOException ignored) { } } } }

  22. Applet slide 7 private String getRegistryHost() { return getCodeBase().getHost(); } private int getRegistryPort() { try { return Integer.parseInt(getParameter("registryPort")); } catch (NumberFormatException e) { return Registry.REGISTRY_PORT; } } private String getRegistryName() { String name = getParameter("registryName"); if (name == null) { name = "DaytimeServlet"; // default } return name; } private String getDateUsingRMIObject() { try { Registry registry = LocateRegistry.getRegistry(getRegistryHost(), getRegistryPort()); DaytimeServer daytime = (DaytimeServer)registry.lookup(getRegistryName()); return daytime.getDate().toString(); } catch (ClassCastException e) { System.out.println("Retrieved object was not a DaytimeServer: " + e.getMessage()); } catch (NotBoundException e) { System.out.println(getRegistryName() + " not bound: " + e.getMessage()); } catch (RemoteException e) { System.out.println("Hit remote exception: " + e.getMessage()); } catch (Exception e) { System.out.println("Problem getting DaytimeServer reference: " + e.getClass().getName() + ": " + e.getMessage()); } return null; } public void actionPerformed(ActionEvent event) { refresh(); }}

  23. You’ll have to fix some stuff • I put the applet’s html and class file in the tomcat/webapps/root directory. • I changed the URL in it so the servlet could be with my other servlets in myexamples. • I upgraded the applet to JApplet with ActionListener from jdk1.1 • Still other deprecated stuff in it I didn’t change.

  24. A class used by the server for RMI import java.util.Date; import java.rmi.Remote; import java.rmi.RemoteException; public interface DaytimeServer extends Remote { public Date getDate() throws RemoteException; }

  25. The servlet slide 1 import java.io.*; import java.net.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import com.oreilly.servlet.RemoteDaemonHttpServlet; public class DaytimeServlet extends RemoteDaemonHttpServlet implements DaytimeServer { public Date getDate() { return new Date(); } public void init(ServletConfig config) throws ServletException { // As before, if you override init() you have to call super.init() super.init(config); }

  26. Servlet slide 2 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // If the client says "format=object" then // send the Date as a serialized object if ("object".equals(req.getParameter("format"))) { ObjectOutputStream out = new ObjectOutputStream(res.getOutputStream()); out.writeObject(getDate()); } // Otherwise send the Date as a normal ASCII string else { PrintWriter out = res.getWriter(); out.println(getDate().toString()); } } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { doGet(req, res); } public void destroy() { // If you override destroy() you also have to call super.destroy() super.destroy(); } // Handle a client's socket connection by spawning a DaytimeConnection // thread. public void handleClient(Socket client) { new DaytimeConnection(this, client).start(); }}

  27. Server slide 3 class DaytimeConnection extends Thread { DaytimeServlet servlet; Socket client; DaytimeConnection(DaytimeServlet servlet, Socket client) { this.servlet = servlet; this.client = client; setPriority(NORM_PRIORITY - 1); } public void run() { try { // Read the first line sent by the client DataInputStream in = new DataInputStream( new BufferedInputStream( client.getInputStream())); String line = in.readLine(); // If it was "object" then return the Date as a serialized object if ("object".equals(line)) { ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); out.writeObject(servlet.getDate()); out.close(); } // Otherwise, send the Date as a normal string else { // Wrap a PrintStream around the Socket's OutputStream PrintStream out = new PrintStream(client.getOutputStream()); out.println(servlet.getDate().toString()); out.close(); } // Be sure to close the connection client.close(); } catch (IOException e) { servlet.getServletContext() .log(e, "IOException while handling client request"); } catch (Exception e) { servlet.getServletContext() .log("Exception while handling client request"); } }}

  28. Changes to servlet • The RMI part is not working ---I need to look at the registry stuff to see why. • One thing… jdk1.5 no longer provides skeleton parts of the rmic method for the server side, only stubs are provided, so I might try doing this one in jdk1.4 (to match what the text describes).

  29. Applet called

  30. Servlet called directly from tomcat

  31. MySQL • Click on the administration tool • It will put a ryg stoplight in the bottom corner of your screen • Select this icon (show me) • Start the server standalone

  32. MySQL

  33. MySQL • MySQL is a real database tool, with security, and an administrative program. (MySQLAdministrator) It can manipulate a number of databases.

  34. Here’s a table I created in the test database

  35. In mysqlcc directory • Run mysqlcc • Select query then select insert (or delete) record. • You can also edit the table itself and change the field datatypes.

  36. mysqlcc allows you to edit tables

  37. A servlet that looks into the test database import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; import java.sql.*; public class Servlet2 extends HttpServletJXGB { //Initialize global variables public void init(ServletConfig config) throws ServletException { super.init(config); } //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = new PrintWriter (response.getOutputStream()); Connection conn=myBroker.getConnection(); Statement stmt=null; String query=""; out.println("<html>"); out.println("<head><title>Servlet1</title></head>"); out.println("<body>"); //out.println("Hello World...Servlet2 is running!<BR>");

  38. A servlet that looks into the test database: slide 2 try { stmt = conn.createStatement (); query="select name,grade,age from table1"; out.println("Query: "+query+"<BR>"); ResultSet rset=stmt.executeQuery( query ); while (rset.next ()){ out.prinln("name: "+rset.getString(1)); out.println("grade: "+rset.getString(2)); out.println("age: "+rset.getString(3)); out.println("<BR>"); } }catch (SQLException e2) { System.out.println("SQLException: "+e2); }finally { try{if(stmt != null) {stmt.close();}} catch(SQLException e1){System.out.println("SQLException: "+e1);} myBroker.freeConnection(conn); // Release connection back to pool } out.println("Querying a MySQL table!<BR>"); out.println("</body></html>"); out.close(); } //Process the HTTP Post request public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public String getServletInfo() { return "Servlet 2"; } }

  39. HttpServletJXGB: a special database broker class /** * Database Global Broker Superclass. * @version 1.0.0 7/28/99 * @author Marc A. Mnich */ import java.sql.*; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import sun.misc.*; import java.util.*; import com.javaexchange.dbConnectionBroker.*; import org.gjt.mm.mysql.*; /** * Creates a two-tier database connection pool that can be shared * by many servlets through inheritance. * @version 1.0.0 7/28/99 * @author Marc A. Mnich */ public class HttpServletJXGB extends HttpServlet { protected static DbConnectionBroker myBroker;

  40. HttpServletJXGB slide 2 public void init (ServletConfig config) throws ServletException { super.init(config); if(myBroker == null) { // Only created by first servlet to call Properties p = new Properties(); try { p.load(new FileInputStream("p:\\classes\\JXGBconfig.dat")); String dbDriver = (String) p.get("dbDriver"); String dbServer = (String) p.get("dbServer"); String dbLogin = (String) p.get("dbLogin"); String dbPassword = (String) p.get("dbPassword"); int minConns = Integer.parseInt((String) p.get("minConns")); int maxConns = Integer.parseInt((String) p.get("maxConns")); String logFileString = (String) p.get("logFileString"); double maxConnTime = (new Double((String)p.get("maxConnTime"))).doubleValue(); myBroker = new DbConnectionBroker(dbDriver,dbServer,dbLogin,dbPassword, minConns,maxConns,logFileString,maxConnTime); } catch (FileNotFoundException f) {System.out.println("File not found "+f.toString());} catch (IOException e) {System.out.println("IO Exception "+e.toString());} } } }

  41. .dat file in p:/classes specifies database used by broker dbDriver=org.gjt.mm.mysql.Driver dbServer=jdbc:mysql://localhost/test dbLogin= dbPassword= minConns=10 maxConns=20 logFileString=p:\\classes\\connections.log maxConnTime=2

  42. Querying a mysql table

  43. Applet uses sendPostMessage from HttpMessage class to upload a serailizable object public InputStream sendPostMessage(Serializable obj) throws IOException{ URLConnection con=servlet.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestProperty("Content-Type","application/x-java-serailizable-object"); ObjectOutputStream out= new ObjectOutputStream(con.getOutputStream()); out.writeObject(obj); out.flush(); out.close(); return con.getInputStream(); }

  44. The applet passing & receiving (string) objects from servlet

  45. Printed in system.out (server dos display)

  46. Object applet: refresh display button code private void refresh() { // Fetch and display the time values String s=httpSendObject.getText(); try{ if(s.length()>0){ URL url = new URL( "http://CSCI345.oneonta.edu:8080/myexamples/ObjectServlet"); HttpMessage msg=new HttpMessage(url); InputStream in=msg.sendPostMessage(s); ObjectInputStream br=new ObjectInputStream (in); String tmp=(String) br.readObject(); httpSendObject.setText("msg"+tmp); }//if httpReceiveObject.setText(getHttpObject()); }//try catch(IOException e){} catch(ClassNotFoundException e){} }

  47. ObjectServlet public String getMessage(){ct++;return message+ct;} public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // If the client says "format=object" then // send the Date as a serialized object if ("object".equals(req.getParameter("format"))) { ObjectOutputStream out = new ObjectOutputStream(res.getOutputStream()); out.writeObject(getMessage()); } else{ PrintWriter out = res.getWriter(); out.println(getMessage()); }

  48. ObjectServlet public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ObjectInputStream objin= new ObjectInputStream(req.getInputStream()); try{ String s= (String) objin.readObject(); System.out.println("from applet"+s); } catch(ClassNotFoundException e){System.out.println("class not found ex line 37");} }//method

  49. ObjectServlet public void handleClient(Socket client) { new ObjectConnection(this, client).start(); }} class ObjectConnection extends Thread { ObjectServlet servlet; Socket client;

  50. ObjectServlet, thread continued public ObjectConnection(ObjectServlet servlet, Socket client) { this.servlet = servlet; this.client = client; setPriority(NORM_PRIORITY - 1); } public void run() { try { // Read the first line sent by the client ObjectInputStream in = new ObjectInputStream( client.getInputStream()); String line = (String) in.readLine(); // If it was "object" then return the message as a serialized object if ("object".equals(line)) { ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); out.writeObject(servlet.getMessage()); out.close(); } // Be sure to close the connection client.close(); } catch (IOException e) { servlet.getServletContext() .log(e, "IOException while handling client request"); } catch (Exception e) { servlet.getServletContext() .log("Exception while handling client request"); } }}

More Related