CS4273: Distributed System Technologies and Programming I Lecture 9: Java Servlets CSlab Setting of Java Servlet Servlet Engine searches files in directory “/usr/local/jt/webapps”. To facilitate access to each person’s files, CSlab has made a link: ln -s /home/lec/jia/www/java/js /usr/local/jt/webapps/jia “/usr/jt/webapps/jia/” “~jia/www/java/js/” 1. • • 2. 3. The servlet engine searches files relative from directory: /usr/local/jt/webapps/ http://jserv.cs.cityu.edu.hk:8080/jia/servlet/XXX is mapped to: “~jia/www/java/js/” + “WEB-INF/classes/” + XXX, because: http://jserv.cs.cityu.edu.hk:8080/jia /usr/local/jt/webapps/jia ~jia/www/java/js/ servlet /WEB-INF/classes All servlet *.class files MUST be in directory: ~jia/www/java/js/WEB-INF/classes/ The corresponding URL is: http://jserv.cs.cityu.edu.hk:8080/jia/servlet/GetServlet All .html files MUST be in directory: ~jia/www/java/js/html/ The corresponding URL is: http://jserv.cs.cityu.edu.hk:8080/jia/html/test.html 2 Your personal directory setting 1. 2. 3. 4. CSlab already made a link from /usr/jt/webapps/501234 to your personal directory “~501234/www/java/js” in CSlab account (501234 is your student number). A copy of all sample programs is in /public/cs4273.tar (zipped at ~jia/www). You can un-zip all files into your directory “~501234/www/” by UNIX commands: cd www // change dir to tar –xvf /public/cs4273.tar // un-zip files into “~501234/www/java/js” All files are in directories “www/java/js/WEB-INF/classes/”, “www/java/js/html/”. To run servlet in “~501234/www/java/js/WEB-INF/classes/GetServlet.class”, URL is: http://jserv.cs.cityu.edu.hk:8080/501234/servlet/GetServlet To run a servlet by a html file in “~501234/www/java/js/html/test.html”, URL is: http://jserv.cs.cityu.edu.hk:8080/501234/html/test.html Note: 1) servEngine cannot detect any change of your program until it restarts. In current setting, servEngine auto-restarts every 20 min. Wait for about 20 min to refresh a page. 2) For each servlet, you need to add a new item in file …/js/WEB-INF/web.xml 3 Java Servlet • Servlet runs on the web site. To enable servlets, it needs to install a servlet engine (e.g., Jserv, or Tomcat), which is a module of a web-server and runs inside the web-server process. • Servlet replaces CGI program to link clients (in browser) to back-end servers. Servlet generates HTML pages, sent back to browser for display, similar to ASP. • Servlet can support many protocols of request / response type, such as HTTP, URL, FTP, SMTP. That’s, any requests coming in the form of these protocols can be processed by a servlet (Servlet API defines the support of these protocols). • The most common protocol that Servlet supports is HTTP. 4 Servlet Life Cycle Servlets run on the web server as part of the web-server process. The web-server initializes, invokes and destroys servlet instances. It invokes servlets via Servlet interface, consisting of three methods: • init(). It is called only once, when the servlet is first loaded. It is guaranteed to finish before any other calls are made to the servlet. • service(). Each request from a client results in a single call to this method. It receives (from the web server) a ServletRequest object & a ServletResponse object to get request / send reply to clients. • destroy(). It is called to allow your servlet to clean up any resources. Most of the time, it is an empty method. 5 A Simple Servlet http://jserv...hk:8080/jia/servlet/GenericServlet import javax.servlet.*; public class GenericServlet implements Servlet{ private ServletConfig config; public void init (ServletConfig config) throws ServletException { this.config = config; } public void destroy() {} // do nothing public ServletConfig getServletConfig() { return config; } public String getServletInfo() { return “A Simple Servlet”; } public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException { res.setContentType( “text/html” ); PrintWriter out = res.getWriter(); out.println( “<html>” ); out.println( “<head>” ); out.println( “<title>A Simple Servlet</title>” ); out.println( “</head>” ); out.println( “<body>” ); out.println( “<h1>Hello Servlet</h1>” ); ………… out.close(); } } 6 Http Servlet The servlet package has two abstract classes that implement interface Servlet: GenericServlet from package javax.servlet HttpServlet from package javax.servlet.http • HttpServlet overrides the key method service() by adding the code to distinguish HTTP requests and invokes corresponding methods: – – – – – – doPost() doGet() doHead() doDelete() doOption() doTrace() • Most of programs extend class HttpServlet, and implement methods doPost() and doGet(). 7 Example of an HTTP servlet import javax.servlet.*; import javax.servlet.http.*; public class GetServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter output; // content type response.setContentType( "text/html" ); output = response.getWriter(); String name = request.getParameter( "customer" ); String addr = request.getParameter( "address" ); // create and send HTML page to client output.println( "<HTML><HEAD><TITLE>" ); output.println( "A Simple Servlet Example" ); output.println( "</TITLE></HEAD><BODY>" ); output.println( "<H1>Welcome to Servlets</H1>" ); output.println( "Dear " + name + "<br>"); output.println( "How are you at " + addr + "?<br>" ); output.println( "</BODY></HTML>" ); output.close(); // close PrintWriter stream } 8 HttpServletRequest / HttpServletResponse • Interfaces HttpServletRequest and HttpServletResponse extend interfaces ServletRequest and ServletResponse. • The methods of HttpServlet receives two parameters: a HttpServletRequest object, which contains the request from the client, and a HttpServletResponse object, which contains the response to the client. • When a client makes a HttpServlet call, the web server creates a HttpServletRequest and a HttpServletResponse object, and passes them to doGet() or doPost() methods. 9 HttpServletRequest Some important methods of HttpServletRequest : • String getParameter (String name) returns the value of the named parameter • Enumeration getParameterNames() returns names of all the parameters sent to servlet • String[] getParameterValues( String name) returns an array of values of the named parameter • Cookie[] getCookies() • HttpSession getSession(Boolean create) 10 HttpServletResponse Some important methods of HttpServletResponse : • void setContentType (String type) specifies the MIME type of the response to the browser, e.g., “text/html”. • PrintWriter getWriter() obtains a character-based output stream. • ServletOutputStream getOutputStream() obtains a byte-based output stream. • void addCookie (Cookie cookie) 11 HTML file for doGet Servlet N.B. URL: http://jserv.cs.cityu.edu.hk:8080/jia/html/GetServlet.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <!-- Fig. 29.6: HTTPGetServlet.html --> <HEAD> <TITLE>Servlet HTTP GET Example</TITLE> </HEAD> <BODY> <FORM ACTION="http://jserv.cs.cityu.edu.hk:8080/jia/servlet/GetServlet" METHOD="GET"> Name <input name="customer" size=47> <p> Working Address <input name="address" size=40> <p> <P>Click the button to connect the servlet</P> <INPUT TYPE="submit" VALUE="Get HTML Document"> </FORM> </BODY> </HTML> 12 DoGet import javax.servlet.*; import javax.servlet.http.*; public class GetServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { PrintWriter output; // content type response.setContentType( "text/html" ); output = response.getWriter(); String name = request.getParameter( "customer" ); String addr = request.getParameter( "address" ); // create and send HTML page to client output.println( "<HTML><HEAD><TITLE>" ); output.println( "A Simple Servlet Example" ); output.println( "</TITLE></HEAD><BODY>" ); output.println( "<H1>Welcome to Servlets</H1>" ); output.println( "Dear " + name + "<br>"); output.println( "How are you at " + addr + "?<br>" ); output.println( "</BODY></HTML>" ); output.close(); // close PrintWriter stream } 13 HTML file for doPost Servlet <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <!-- Fig. 29.8: HTTPPostServlet.html --> <HEAD> <TITLE>Servlet HTTP Post Example</TITLE> </HEAD> <BODY> <FORM ACTION="http://jserv.cs.cityu.edu.hk:8080/jia/servlet/PostServlet" METHOD="POST"> What is your favorite pet?<BR><BR> <INPUT TYPE="radio" NAME="animal" VALUE="dog">Dog<BR> <INPUT TYPE="radio" NAME="animal" VALUE="cat">Cat<BR> <INPUT TYPE="radio" NAME="animal" VALUE="bird">Bird<BR> <INPUT TYPE="radio" NAME="animal" VALUE="snake">Snake<BR> <INPUT TYPE="radio" NAME="animal" VALUE="none" CHECKED>None <BR><BR><INPUT TYPE="submit" VALUE="Submit"> <INPUT TYPE="reset"> </FORM> </BODY></HTML> 14 DoPost public class PostServlet extends HttpServlet { private String animalNames[] ={ "dog", "cat", "bird", …}; public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { int animals[] = null, total = 0; //read in initial data of animals[] from a file // ....... value = request.getParameter( "animal" ); // update survey data in animals[] for ( int i = 0; i < animalNames.length; ++i ) if ( value.equals( animalNames[ i ] ) ) ++animals[ i ]; // write animals[] to file & calculate % // send a message & survey results to client response.setContentType( "text/html" ); PrintWriter output = response.getWriter(); output.println( "<html>" ); output.println( "<title>Thank you!</title>" ); output.println( "Thank you for participating." ); output.println( "<BR>Results:<PRE>" ); // ....... println results. output.println( "</PRE></html>"); output.close(); } } 15 Servlet Database Connection • A servlet can connect to a DB server using JDBC in the same way as CGI programs. • A servlet can be started directly from browser, e.g., http://jserv.cs.cityu.edu.hk:8080/jia/servlet/Coffee, if this servlet implements doGet method. • The servlet generates output in HTTP HTML format and passes them back server to the browser for display. Servlet JDBC DBMS system 16 A Servlet JDBC Paired with HTML public class Coffee extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String url = jdbc:mysql://jserv.cs.cityu.edu.hk: 3306/db_jdemo"; String query = "select COF_NAME, PRICE from COFFEES"; response.setContentType("text/html"); PrintWriter out = response.getWriter(); Class.forName("com.mysql.jdbc.Driver"); con = DriverManager.getConnection(url, "jdemo", "apple1"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(query); out.println("<HTML><HEAD><TITLE>"); out.println("</TITLE></HEAD>"); ………….. HTML format… out.println("<table border=1>"); out.println("<tr><th>Name<th>Price"); while (rs.next()) { String s = rs.getString("COF_NAME"); float f = rs.getFloat("PRICE"); String text = "<tr><td>" + s + "<td>" + f; out.println(text); } stmt.close(); con.close(); out.println("</table>"); out.println("</BODY></HTML>"); out.close(); } } 17 Applet and Servlet • • • • Servlet can be used with Applet as a replacement of CGI programs. Applet starts a servlet by POST (or GET), same way as starting a CGI program. Applet passes parameters to servlet in the same format as HTML form, e.g., “name=X+Jia&addr=CityU &ID=5012344”. Servlet can use getParameter to get parameter values. The Applet processes the results from the servlet in the same way as from a CGI program (suppose servlet sends results back in the same format as CGI). HTTP server must be in version 1.1 or above. HTTP Applet It uses protocol: server POST /jia/servlet/CoffeeServlet HTTP/1.1 Servlet JDBC DBMS system 18 An Applet connecting to a Servlet // java/js/WEB-INF/classes/CoffeeApplet.java // http://jserv.cs.cityu.edu.hk:8080/jia/html/test.html public class CoffeeApplet extends Applet implements Runnable { public synchronized void start() { if (worker == null) { Thread worker = new Thread(this); worker.start(); } } public void run() { Socket s; String sdata = “type=select_COFFEES”; DataInputStream in; PrintStream out; s = new Socket("jserv.cs.cityu.edu.hk",8080); in = new DataInputStream(s.getInputStream()); out = new PrintStream(s.getOutputStream()); out.println("POST /jia/servlet/CoffeeServlet HTTP/1.1"); out.println("Host: jserv.cs.cityu.edu.hk"); out.println("Content-type: application/x-www-form-urlencoded"); out.println("Content-length: " + sdata.length()); out.println(""); out.println(sdata); String line = in.readLine(); while (! line.equals("START_DATA")) line = in.readLine(); while (! line.equals("END")) { results.addElement(line); line = in.readLine(); } out.close(); in.close(); } 19 The Servlet Paired with Applet in JDBC • The servlet working with an applet is similar to the CGI program in the 3-tier structure of JDBC. • The servlet gets requests from applet via getParameter on “request” object. Note: the string posted from applet must have the parameter in the correct format! • The servlet sends reply back to applet via println on “response” object. The servlet prepares reply to applet in a sequence of string lines, same as the CGI in 3-tier. Note: applet cannot process HTML statements easily. • The applet working with the servlet is almost the same as the applet in the 3-tier structure of JDBC (except the format of request). 20 Servlet paired with the Applet public class CoffeeServlet extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); a_req = request.getParameter("type"); if (a_req.equals("select_COFFEES")) { line = ReqSql(); out.println("START_DATA"); out.println(line); out.println(“END”); } } static String ReqSql() { String url = "jdbc:mysql://jserv.cs.cityu.edu.hk: 3306/db_jdemo"; String query = "select COF_NAME, PRICE from COFFEES"; // make JDBC connection and executeQuery ………….. // process ResultSet to a line of string "results“ ………….. return(results.toString()); } } 21 Servlet Cookies HTTP server is stateless, i.e., it does not keep any info about the clients. Some applications require the response to client requests depends on the info from the client earlier. Cookie is for this purpose. • Cookies are extracted from the client’s data sent to the servlet. They are sent back to the client to store at the client side. • A cookie is associated with an age. When the age expires, it will be removed. • The cookies are included in the header of request and sent to the servlet together with request (new cookies are sent back browser via response. The servlet can analyse cookies and reponse to the requests accordingly. • HTTPSession is a similar technology as the Cookie for the same purpose. 2. send cookies to browser for storage Browser 3. include cookies in 1. generate cookies from client-requst Servlet the next client-request 22 Methods on Cookies • • • • • Cookies are strings, defined in javax.servlet.http.Cookie. Construct a Cookie: Cookie cookie = new Cookie( name, value); Set an age for a cookie: cookie.setMaxAge (seconds); Add a cookie to a response to the client: response.addCookie (cookie); Get cookies from a client’s request: Cookie cookies[]; cookies = request.getCookies(); • Get cookie attributes: cookies[i].getname(); cookies[i].getValue(); • Analyse cookies one by one: for (i = 0; i < cookies.length; i++) { cookies[i].getname() … cookies[i].getValue(); } 23 An example of using Cookies public class CookieServlet extends HttpServlet { // must precede getWriter private final static String names[] = response.addCookie( c ); { "C", "C++", "Java", "Visual Basic 6" }; response.setContentType( "text/html" ); private final static String isbn[] = { "0-13PrintWriter output = response.getWriter(); 226119-7", "0-13-5289-6", "0-13-0125-5", utput.println( "<HTML><HEAD><TITLE>" ); "0-13-45695-5"}; output.println( "Cookies" ); public void doPost( HttpServletRequest request, output.println( "</TITLE></HEAD><BODY>" ); HttpServletResponse response ) output.println( "<P>Welcome to Cookies!<BR>" ); throws ServletException, IOException { output.println( "<P>"+lang+" is a great language." ); String language = output.println( "</BODY></HTML>" ); request.getParameter( "lang" ); output.close(); // close stream Cookie c = new Cookie( language, } getISBN( language ) ); c.setMaxAge( 120 ); // cookie expires 24 An example of using Cookies (Cont.) public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException{ Cookie cookies = request.getCookies(); response.setContentType( "text/html" ); PrintWriter output = response.getWriter(); output.println( "<HTML><HEAD><TITLE>" ); output.println( "Cookies II" ); output.println( "</TITLE></HEAD><BODY>" ); if ( cookies != null && cookies.length != 0 ) { output.println( "<H1>Recommendations</H1>" ); for ( int i = 0; i < cookies.length; i++ ) output.println(cookies[ i ].getName() + " Programming," + " ISBN#: " + cookies[ i ].getValue() + "<BR>" ); } else { output.println( "</BODY></HTML>" ); output.close(); // close stream } private String getISBN( String lang ) { for ( int i = 0; i < names.length; ++i ) if (lang.equals(names[i])) return isbn[i]; } } output.println( "<H1>No Recommendations</H1>" ); output.println( "The cookies have expired." ); } 25 HttpSession and Session Tracking • When customers at an on-line store add items to their shopping carts, how does the server know what are already in the carts? • When customers proceed to checkout, how can the server determine which previously created carts are theirs? • HTTP is stateless. HttpSession is the solution to provide session tracking for clients. • HttpSession is built on top of Cookies. It generates & maintains session IDs transparently. 26 Steps and APIs for Session Tracking • Access the session embedded in Http request object: HttpSession session = request.getSession(true/false); • Set attribute value in the session: session.setAttribute(“key”, value); • Get attribute value of the session: xxxclass value = session.getAttribute(“xxxkey”); • Get other information of the session: session.getId(); getCreationTime(), getLastAccessedTime(), …. Boolean session.isNew(); • Remove session data: removeAttribute("key"); 27 Rewrite the Example of Cookies by Sessions public class SessionTracking extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String lang = request.getParameter( "lang" ); HttpSession session = request.getSession( true ); public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { HttpSession session = request.getSession( false ); if ( session != null ) valueNames = session.getAttributeNames(); else valueNames = null; //setAttribute passes session to browser via output if ( valueNames != null) { session.setAttribute( lang, getISBN( lang)); output.println( "<H1>List of your purchase</H1>" ); … ……. output.println(…+ session.isNew()?...); while ( valueNames.hasMoreElements() ) { name = valueNames.nextElement().toString(); output.println(…+ session.getID()...); value = session.getAttribute( name ).toString(); output.println(…+ session.getCreationTime()...); output.println( name + …+ value + "<BR>" ); output.println(…+ session.getLastAccessedTime()); } …….. } else output.println( “No purchase" ); } 28 Comparisons of Cookies and Sessions • Cookies is persistent beyond closedown of browser (info is stored on disk); while Session is only valid for one browsing-session (stored in browser’s memory). • Cookies have limited size (around 300 cookies for a server, 20 cookies per client and 4K bytes of data per cookie); while session data has no limit of size. • Due to security reason, some browsers don’t support cookies (or they can be turned off). 29