• Fat Client
Architectural choices for designing a Web-accessible calendar
– Put processing such as ordering the monthly view, etc. on the client (e.g. an applet)
• Advantages:
– reduces cycles on the server, – allows an independent socket back to server
• Disadvantages:
– requires server side processing to access database anyway
• Thin Client
Architectural choices for designing a Web-accessible calendar
– Keep processing off the client.. Treat it like little more than a display
• Advantages:
– performance largely independent of client platform – You needed to write a server side process anyway
• Disadvantages:
– Program can get large & complicated
Fat Client Approach (standard client-server)
• Need running server process on the http server machine • Applet requests a connection • Server process accepts and spans a thread to handle the connection
Opening a socket from Java
example from Core Java
import java.io.*; Import io for reading & writing streams & net for The socket import java.net*; class SocketTest { public static void main(String[] args)
Use the try/catch formula to deal with exceptions
{ try { Socket t = new Socket("time-A.timefreq.bldrdoc.gov",13); BufferedReader is = new BufferedReader (new InputStreamReader(t.getInputStream())); boolean more = true; while (more) { String str = is.readLine(); if (str == null) more = false; else System.out.println(str); } } catch(IOException e) { System.out.println("Error" + e); } }}
Threaded Echo Handler
from Core Java
import java.io.*; import java.net.*; handler code manages single socket
class ThreadedEchoHandler extends Thread { Socket incoming; int counter; ThreadedEchoHandler(Socket i, int c) { incoming = i; counter = c; } public void run() method for thread { try { DataInputStream in = new DataInputStream(incoming.getInputStream()); PrintStream out = new PrintStream(incoming.getOutputStream()); out.println( "Hello! Enter BYE to exit.\r" );
Threaded Echo Handler (cont)
boolean done = false; Read & write strings while (!done) { String str = in.readLine(); if (str == null) done = true; else { out.println("Echo (" + counter + "): " + str + "\r"); if (str.trim().equals("BYE")) done = true; } } incoming.close();
} catch (Exception e) { System.out.println(e); }
} }
Threaded Echo Server
from Core Java
class ThreadedEchoServer { public static void main(String[] args ) { int i = 1; Listens on 8189 for a connection request try { ServerSocket s = new ServerSocket(8189); for (;;) { Socket incoming = s.accept( ); System.out.println("Spawning " + i); new ThreadedEchoHandler(incoming, i).start(); Creates a handler for the connection i++; } } catch (Exception e) { System.out.println(e); }}}
import java.awt.*; import java.applet.*; import java.net.*; import java.io.*; import java.awt.event.*; public class NetCalcApplet extends Applet implements ActionListe { public void init() { try { c = new Socket(InetAddress.getLocalHost(), 4000); in = new BufferedReader(new InputStreamReader(c.getInputStrea out = new PrintWriter(c.getOutputStream(),true); setLayout(new BorderLayout()); display = new TextField("0"); display.setEditable(false); add("North", display); Panel p = new Panel();
Using this approach for a ClientServer Calculator
Calculator client (cont)
p.setLayout(new GridLayout(4, 4)); for (int i = 0; i <= 9; i++) addButton(p,("" + (char)('0' + i))); addButton(p,"."); addButton(p,"="); addButton(p,"+"); addButton(p,"-"); addButton(p,"*"); addButton(p,"/"); add("Center", p); } catch(IOException e) {System.out.println("Error" + e); } } public void addButton(Container c, String s) { Button b = new Button(s); c.add(b); b.addActionListener(this); }
Calculator Client (eventhandling)
public void actionPerformed(ActionEvent evt) { String s = evt.getActionCommand(); char ch = s.charAt(0); if ('0' <= ch && ch <= '9' || ch == '.') { if (start) display.setText(s); else display.setText(display.getText() + s); start = false; } else { if (start) { if (s.equals("-")) { display.setText(s); start = false; } } else { if (state1) { ag = ""+ display.getText(); op = s;
Calculator client (eventhandling)
{ out.println(ag); out.println(op); out.println(display.getText()); state1 = true; start = true; try { ag = in.readLine(); display.setText(ag); } catch (Exception e) { System.out.println(e); } op = s; start = true;} } } }
Calculator client (declarations)
private TextField display; private String ag = "0"; private String op = "="; private boolean state1 = true; private boolean start = true; Socket c; BufferedReader in; PrintWriter out; private String answ; }
Calculator server (do the comp)
import java.io.*; import java.net.*; import corejava.*; class ThreadedCalcHandler extends Thread { Socket incoming; int counter; ThreadedCalcHandler(Socket i, int c) { incoming = i; counter = c; } public void run() { try { DataInputStream in = new DataInputStream(incoming.getInputStream()); PrintStream out = new PrintStream(incoming.getOutputStream( boolean done = false;
Calculator server (do the comp)
while (!done) { arg1 = Format.atof(in.readLine()); String Op = in.readLine(); arg2 = Format.atof(in.readLine()); answ = arg1; if(Op.equals("+")) answ += arg2; else if (Op.equals("-")) answ -= arg2; else if (Op.equals("*")) answ *= arg2; else if (Op.equals("/")) answ /= arg2; out.println(String.valueOf(answ)); } incoming.close(); } catch (Exception e) { System.out.println(e); } } private double arg1; private double arg2; private double answ; }
Calculator Server (accept request)
class ThreadedCalcServer { public static void main(String[] args { int i = 1; try { ServerSocket s = new ServerSocket(4000); for (;;) { Socket incoming = s.accept( ); System.out.println("Spawning " + i); new ThreadedCalcHandler(incoming, i).start(); i++; } } catch (Exception e) { System.out.println(e); } } }
Fat Client for Calendar
Applet Would access calendar object on client machine to generate views Would exchange date information with sever to retrieve appointments Requires: moving current calendar to applet (change constructor to init method) Writing server for accessing database
Thin Client Approach
Takes advantage of built-in interactive features of HTML (e.g. Common Gateway Interface) Your application must: 1. Generate HTTP headers and HTML source for display on client 2. Accept HTML GET or POST actions to get information from client This is really pretty much just like CGI scripting
Thin Client Approaches
• Standard CGI- roll your own in any language but must handle protocol yourself • Servlet- special relation to HTTP server for java (non executable) access & run • Active Server Pages (asp) lets you mix standard HTML & generated content (simplifies dealing with protocol) • Java Server Pages (jsp) similar to asp but uses Java servlets
What should you do?
Because calendars don’t require mixing a lot of variable & fixed contents servlets are likely to be an easy way to get there..
A monthly view generated by inserting table markup in our calendar example
Running IIS on Windows XP Professional Many people do not know that Windows XP Professional includes a fully functional web server, Microsoft IIS 5.1. For a small office or home, this is incredibly convenient. If you're a developer who wants to try web development with HTML, Javascript, Active Server Pages (ASP), or VBScript, having IIS can allow you to experiment quickly with files on your local system. Of course, you could always download and install the free and robust Apache web server, but IIS is somewhat simpler and the documentation is better.
What Web server do I use?
Surprisingly most of the major webservers can be had for free
IIS- from MS, easy to use, just install from your disk, but not a major
commercial player
Apache- the major Unix/Linux commercial server, Open Source,
secure but less featured, manageable than some proprietary servers
Websphere – ibm product, supports Eclipse & SWT, webservice
extensions, etc.
Weblogic – from BEA, a sophisticated server from small vendor,
optimized for b2b, webservices
Installing IIS on Windows XP Professional
The Internet Information Server (IIS) is not installed by default on Windows XP. To install it, one must log in under an account with administrator privileges, and go to "Control Panel"->"Add Remove Programs"->"Add/Remove Windows Components." Just check the "Internet Information Services" checkbox and complete the installation. (Note, if you click the "Details..." button, you can also install Microsoft's free FTP server.)
Once that finishes, you will have a directory called c:\Inetpub\wwwroot on your hard drive that contain the files that your web server will serve. To test your server, use Internet Explorer or Mozilla and type in "http://localhost" or "http://127.0.0.1" in the URL. You will see either an "Under Contruction" page or a Microsoft page that says your web service is now running. These are default files installed by IIS in the wwwroot directory, and it is safe to delete them if you want a barebones IIS installation. Create a text file called "Default.asp", type something in it, and save it to the wwwroot directory. When you reload your site again, you will see the file you just made displayed in the browser. Now you are free to experiment with HTML, Javascript, CSS, etc.
Slides from Marty Hall
http://courses.coreservlets.com/
Start & Stop the Server
Jsp stuff
Dietel & Deitel Html page to servlet
Deitel Guest Book Form Guest Book
Deitel & deitel servlet example
// Fig. 19.16: GuestBookServlet.java // Three-Tier Example import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; import java.sql.*; public class GuestBookServlet extends HttpServlet { private Statement statement = null; private Connection connection = null; private String URL = "jdbc:odbc:GuestBook"; public void init( ServletConfig config ) throws ServletException { super.init( config );
Open the DB
try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); connection = DriverManager.getConnection( URL, "", "" );
} catch ( Exception e ) { e.printStackTrace(); connection = null; }
}
Get data from html form
public void doPost( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException { String email, firstName, lastName, company, snailmailList, cppList, javaList, vbList, iwwwList;
Read data from the submitted form
email = req.getParameter( "Email" ); firstName = req.getParameter( "FirstName" ); lastName = req.getParameter( "LastName" ); company = req.getParameter( "Company" ); snailmailList = req.getParameter( "mail" ); cppList = req.getParameter( "c_cpp" ); javaList = req.getParameter( "java" ); vbList = req.getParameter( "vb" ); iwwwList = req.getParameter( "iwww" );
Send a message back to the page
(note that output is going to standard out)
PrintWriter output = res.getWriter(); res.setContentType( "text/html" );
if ( email.equals( "" ) || firstName.equals( "" ) || lastName.equals( "" ) ) { output.println( "
Please click the back " + "button and fill in all " + "fields.
" ); output.close(); return; }
D&D’s extra lines to match their standard db
/* Note: The GuestBook database actually contains fields * Address1, Address2, City, State and Zip that are not * used in this example. However, the insert into the * database must still account for these fields. */ boolean success = insertIntoDB( "'" + email + "','" + firstName + "','" + lastName + "','" + company + "',' ',' ',' ',' ',' ','" + ( snailmailList != null ? "yes" : "no" ) + "','" + ( cppList != null ? "yes" : "no" ) + "','" + ( javaList != null ? "yes" : "no" ) + "','" + ( vbList != null ? "yes" : "no" ) + "','" + ( iwwwList != null ? "yes" : "no" ) + "'" ); if ( success ) output.print( "
Thank you " + firstName + " for registering.
" ); else output.print( "
An error occurred. " + "Please try again later.
" ); output.close(); }
The database interaction
private boolean insertIntoDB( String stringtoinsert ) { try { statement = connection.createStatement(); statement.execute( "INSERT INTO GuestBook values (" + stringtoinsert + ");" ); statement.close(); } catch ( Exception e ) { System.err.println( "ERROR: Problems with adding new entry" ); e.printStackTrace(); return false; } return true; }
The destructor
public void destroy() { try { connection.close(); } catch( Exception e ) { System.err.println( "Problem closing the database" ); } }
}
Don’t know if we want/need this MVP stuff…