servlets chapter 10 applet/servlet communication (with a database twist)

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

Post on 21-Dec-2015

234 views

Category:

Documents


0 download

TRANSCRIPT

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

Servlets Chapter 10

Applet/servlet communication

(with a database twist)

Page 2: 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).

• 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.

Page 3: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 4: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 5: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Before JDK1.1

1. Establish http connection to CGI program on server. The applet acts like a browser.

2. 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.

Page 6: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 7: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 8: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 9: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 10: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.)

Page 11: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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

Page 12: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 13: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 14: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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).

Page 15: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet called

Page 16: Servlets Chapter 10 Applet/servlet communication (with a database twist)

The applet slide#1import 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 interfaceContainer 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);

Page 17: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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); }

Page 18: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet slide 3private 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; } }

Page 19: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet slide 4private 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; } }

Page 20: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet slide 5private 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) { } } } }

Page 21: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet slide6private 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) { } } } }

Page 22: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet slide 7private 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(); }}

Page 23: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 24: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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;

}

Page 25: Servlets Chapter 10 Applet/servlet communication (with a database twist)

The servlet slide 1import java.io.*;import java.net.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import com.oreilly.servlet.RemoteDaemonHttpServlet;public class DaytimeServlet extends RemoteDaemonHttpServletimplements 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); }

Page 26: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Servlet slide 2public 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(); }}

Page 27: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Server slide 3class 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"); } }}

Page 28: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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).

Page 29: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Applet called

Page 30: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Servlet called directly from tomcat

Page 31: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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

Page 32: Servlets Chapter 10 Applet/servlet communication (with a database twist)

MySQL

Page 33: Servlets Chapter 10 Applet/servlet communication (with a database twist)

MySQL• MySQL is a real database tool, with security, and an

administrative program. (MySQLAdministrator) It can manipulate a number of databases.

Page 34: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Here’s a table I created in the test database

Page 35: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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.

Page 36: Servlets Chapter 10 Applet/servlet communication (with a database twist)

mysqlcc allows you to edit tables

Page 37: Servlets Chapter 10 Applet/servlet communication (with a database twist)

A servlet that looks into the test databaseimport 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>");

Page 38: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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"; }}

Page 39: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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;

Page 40: Servlets Chapter 10 Applet/servlet communication (with a database twist)

HttpServletJXGB slide 2public 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());}}

}}

Page 41: Servlets Chapter 10 Applet/servlet communication (with a database twist)

.dat file in p:/classes specifies database used by broker

dbDriver=org.gjt.mm.mysql.DriverdbServer=jdbc:mysql://localhost/testdbLogin=dbPassword=minConns=10maxConns=20logFileString=p:\\classes\\connections.logmaxConnTime=2

Page 42: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Querying a mysql table

Page 43: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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();

}

Page 44: Servlets Chapter 10 Applet/servlet communication (with a database twist)

The applet passing & receiving (string) objects from servlet

Page 45: Servlets Chapter 10 Applet/servlet communication (with a database twist)

Printed in system.out (server dos display)

Page 46: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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); }//ifhttpReceiveObject.setText(getHttpObject());}//trycatch(IOException e){}catch(ClassNotFoundException e){} }

Page 47: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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());

}

Page 48: Servlets Chapter 10 Applet/servlet communication (with a database twist)

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

Page 49: Servlets Chapter 10 Applet/servlet communication (with a database twist)

ObjectServlet

public void handleClient(Socket client) {

new ObjectConnection(this, client).start();

}}

class ObjectConnection extends Thread {

ObjectServlet servlet;

Socket client;

Page 50: Servlets Chapter 10 Applet/servlet communication (with a database twist)

ObjectServlet, thread continuedpublic 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"); } }}