What is a Servlet?

Preview:

DESCRIPTION

What is a Servlet?. A servlet is a java class that extends an application hosted on a web server. Handles the HTTP request-response process (for our purposes) Often thought of as an applet that runs on a server. - PowerPoint PPT Presentation

Citation preview

What is a Servlet?• A servlet is a java class that extends an application

hosted on a web server.• Handles the HTTP request-response process (for our

purposes)

• Often thought of as an applet that runs on a server.• Provides a component base architecture for web

development, using the Java Platform• The foundation for Java Server Pages (JSP).• Alternative to CGI scripting and platform specific

server side applications.

Common Uses

• Processing and/or storing data submitted by an HTML form.

• Providing dynamic content, e.g. returning the results of a database query to the client.

• Managing state information on top of the stateless HTTP, e.g. for an online shopping cart system which manages shopping carts for many concurrent customers and maps every request to the right customer.

Architectural Roles

• Servlets provide the middle tier in a three or multi-tier system.

• Servlets provide logic and/or traffic control for requests/response to the server.

• Servlets allow web developers to remove code from the client and place the logic on the server.

What is required?• Servlets are not run in the same sense as applets and

applications.• Since they extend a web server, they require a servlet

container to function.• A servlet container is a part of a web server or

application server that provides the network services over which request and response are sent.

• Contains and manages the servlets through there lifecycle.

• The container provides other services as well.

J2EE Container

Web Container/Servlet engine

Browser

Servlets

Web Server

Deployment Descriptor

Java Classes

web.xml

Deployment Descriptor is used to configure web applications that are hosted in the App Server.

Servlet Life Cycle• Initialization– the servlet engine loads the servlet’s *.class file in the JVM

memory space and initializes any objects• Execution– when a servlet request is made,

• a ServletRequest object is sent with all information about the request

• a ServletResponse object is used to return the response

• Destruction– the servlet cleans up allocated resources and shuts down

Client Interaction

• When a servlet accepts a call from a client, it receives two objects: – A ServletRequest, which encapsulates the

communication from the client to the server. – A ServletResponse, which encapsulates the

communication from the servlet back to the client.

• ServletRequest and ServletResponse are interfaces defined by the javax.servlet package.

The ServletRequest Interface

• The ServletRequest interface allows the servlet access to: – Information such as the names of the parameters passed in by the

client, the protocol (scheme) being used by the client, and the names of the remote host that made the request and the server that received it.

– The input stream, ServletInputStream. Servlets use the input stream to get data from clients that use application protocols such as the HTTP POST and PUT methods.

• Interfaces that extend ServletRequest interface allow the servlet to retrieve more protocol-specific data. For example, the HttpServletRequest interface contains methods for accessing HTTP-specific header information.

The ServletResponse Interface

• The ServletResponse interface gives the servlet methods for replying to the client. It: – allows the servlet to set the content length and MIME

type of the reply. – provides an output stream, ServletOutputStream, and

a Writer through which the servlet can send the reply data.

• Interfaces that extend the ServletResponse interface give the servlet more protocol-specific capabilities. – For example, the HttpServletResponse interface

contains methods that allow the servlet to manipulate HTTP-specific header information.

Request Information Example Source Code-1/2

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class RequestInfo extends HttpServlet { public void doGet(HttpServletRequest request,

HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>");

out.println("<title>Request Information Example </title>"); out.println("</head>");out.println("<body>");

Request Information Example Source Code-2/2out.println("<h3>Request Information Example</h3>");out.println("Method: " + request.getMethod());out.println("Request URI: " + request.getRequestURI());out.println("Protocol: " +request.getProtocol());out.println("PathInfo: " + request.getPathInfo());out.println("Remote Address: " + request.getRemoteAddr()); out.println("</body>");out.println("</html>"); } /* We are going to perform the same operations for POST requests as for GET methods, so this method just sends the request to the doGet method.*/public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response);}}

Request Header Example

Additional Capabilities of HTTP Servlets

• Cookies are a mechanism that a servlet uses to have clients hold a small amount of state-information associated with the user. Servlets can use the information in a cookie as the user enters a site (as a low-security user sign-on,for example), as the user navigates around a site (as a repository of user preferences for example), or both.

• HTTP servlets also have objects that provide cookies. The servlet writer uses the cookie API to save data with the client and to retrieve this data.

Cookies

Cookies Source Code – 1/2import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class CookieExample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse

response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); // print out cookies Cookie[] cookies = request.getCookies(); for (int i = 0; i < cookies.length; i++) {

Cookie c = cookies[i];String name = c.getName();String value = c.getValue();

out.println(name + " = " + value);}

Cookies Source Code –2/2

// set a cookie String name = request.getParameter

("cookieName"); if (name != null && name.length() > 0) { String value =

request.getParameter("cookieValue"); Cookie c = new Cookie(name, value); response.addCookie(c);}}}

Servlet Sessions

• Since http protocol is stateless, Java API provides the following techniques for session tracking:– URL rewriting– Cookies– Hidden form fields

Client Server

Response with a Token

Request with a Token

Servlet Sessions

• URL Write – Facilitated through methods in the response interface– http://bradsmachine.com?jsessionid=00988988

• Hidden fields - <input type=“hidden” name=“jsessionid” value=“00988988”>

• Cookies– Cookie c = new Cookie(“uid”, “brad”);– c.setMaxAge(60);– c.setDomain(“bradsmachine”);– c.setPath(“/”);– response.addCookie(c);

• Servlet API requires that web containers implement session tracking using cookies.

HttpSession

• Web containers provide an implementation of this interface to provide session tracking.

• Session objects can be retrieved from the HttpRequest object also provided by the container.HttpSession session = request.getSession();

• If a session object does not exist for the client, one will be created.

• The duration of this session object can be configured in the web.xml file or in a servlet, setMaxInactiveInterval( int interval );

Session Capabilities

• Session tracking is a mechanism that servlets use to maintain state about a series of requests from the same user(that is, requests originating from the same browser) across some period of time.

• session-tracking capabilities. The servlet writer can use these APIs to maintain state between the servlet and the client that persists across multiple connections during some time period.

Sessions

Sessions Source Code –1/2import java.io.*; import java.util.*;import javax.servlet.*; import javax.servlet.http.*;

public class SessionExample extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse

response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(true); // print session info Date created = new Date( session.getCreationTime()); Date accessed = new

Date(session.getLastAccessedTime());

Sessions Source Code –2/2out.println("ID " + session.getId());out.println("Created: " + created);out.println("Last Accessed: " + accessed);String dataName = request.getParameter("dataName"); if (dataName != null && dataName.length() > 0) {String

dataValue = request.getParameter("dataValue"); session.setAttribute(dataName, dataValue);} // print session contents Enumeration e = session.getAttributeNames();

while (e.hasMoreElements()) { String name = String)e.nextElement();

value = session.getAttribute(name).toString(); out.println(name + " = " + value);}}}

Servlets

database connectivity

Servlets and db

• Messaging, storefronts and search engines all require databases.

• Such sites may be complicated to build and have performance issues.

• We will use SQL and JDBC.• The JDBC and servlet API are a good solution

to db issues.

Platform independence

• Servlets written for oracle can easily be modified for sybase, mysql or odbc.

• Text does many connection types. I only do mysql.

Connectors

• Connecting to mysql from java requires a connector.

• Applications and servlets can connect to the db.

• MYSQL listens on port 3306• You’ll have to go to the mysql site to download

mysql-connector-java .zip• Unzip, and put the jar file in your classpath.

Getting connections• Imports:import java.sql.*;

• The first step in using a JDBC driver to get a db connection in your application involves loading the specific driver class into the application’s jvm.

• One way to do it is to use the Class.forName() method:Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);• Once loaded, the driver registers itself with the

java.sql.DriverManager class as an available db driver.• Next step is to ask the driver manager to open a connection to

a given db specified in a URL. The method used is DriverManager.getConnection():

Connection con= DriverManager.getConnection(“jdbc etc”,”user”,”pw”);

MYSQL admin

administration• Some slides show the mysqlcc (control center) but

since we already have apache/php it is easier to continue to use PHPMyAdmin.

• You’ll need apache running to administer mysql using phpmyadmin.

• If Apache and Tomcat run on the same port you’ll have a problem.

• By default, apache is at 80 and tomcat is at 8080 but if you’ve changed those settings you might have trouble.

MYSQL admin and MYSQLcontrol center

• Download and install mysql.• Run MYSQL from the admintool (icon): • A little traffic light icon with a red light will appear lower right

monitor screen. • Rt-click this and select NT. (Selecting showme will open the

mysql admin GUI)• First, shutdown the service, then start the service standalone.• The traffic light should be green indicating that mysql is

running.• MySQLMyAdmin is a good GUI for managing your db

MySQLCC

Some remarks

• Looking at user admin in the control center you can add users or set pws. (rt click user admin selection)

• Security is less tight for the “test” db, so that is where my examples are.

Add user

New user bob

A new table: rt click tables selection in mysql control center

Saving table/viewing table fields

Open table/query/insert record

• Under query type insert record to put some data in

The phonelookup servletimport java.io.*;import java.sql.*;import javax.servlet.*;import javax.servlet.http.*;public class DBPhoneLookup extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection con = null; Statement stmt = null; ResultSet rs = null; res.setContentType("text/html"); PrintWriter out = res.getWriter(); try { // Load (and therefore register) the Oracle Driver Class.forName("org.gjt.mm.mysql.Driver"); // Get a Connection to the database con = DriverManager.getConnection( "jdbc:mysql://localhost/test", "bob", "justabob");//or user= “root”, pw=”” // Create a Statement object stmt = con.createStatement(); // Execute an SQL query, get a ResultSet rs = stmt.executeQuery("SELECT NAME, EMAIL FROM guestlist");//added cmt and id to this // Display the result set as a list out.println("<HTML><HEAD><TITLE>Phonebook</TITLE></HEAD>"); out.println("<BODY>"); out.println("<UL>"); while(rs.next()) { out.println("<LI>" + rs.getString("name") + " " + rs.getString("email")); }//actually added more to get all columns out.println("</UL>"); out.println("</BODY></HTML>"); } catch(ClassNotFoundException e) { out.println("Couldn't load database driver: " + e.getMessage()); } catch(SQLException e) { out.println("SQLException caught: " + e.getMessage()); } finally { // Always close the database connection. try { if (con != null) con.close(); } catch (SQLException ignored) { } } }}

Phone lookup (using guestbook table)

phonebook

• This is about as simple as it could be.• It does not establish a pool of connections – it

just opens one.• It does not get db driver and user/pw from

servlet context or init params. These are hardcoded.

HtmlSQL result class presents query result as an html table

public class HtmlSQLResult { private String sql; private Connection con;

public HtmlSQLResult(String sql, Connection con) { this.sql = sql; this.con = con; }

public String toString() { // can be called at most once StringBuffer out = new StringBuffer();

// Uncomment the following line to display the SQL command at start of table // out.append("Results of SQL Statement: " + sql + "<P>\n");

try { Statement stmt = con.createStatement();

if (stmt.execute(sql)) { // There's a ResultSet to be had ResultSet rs = stmt.getResultSet(); out.append("<TABLE>\n");

ResultSetMetaData rsmd = rs.getMetaData();

int numcols = rsmd.getColumnCount();

continued// Title the table with the result set's column labels out.append("<TR>"); for (int i = 1; i <= numcols; i++) out.append("<TH>" + rsmd.getColumnLabel(i)); out.append("</TR>\n");

while(rs.next()) { out.append("<TR>"); // start a new row for(int i = 1; i <= numcols; i++) { out.append("<TD>"); // start a new data element Object obj = rs.getObject(i); if (obj != null) out.append(obj.toString()); else out.append("&nbsp;"); } out.append("</TR>\n"); }

// End the table out.append("</TABLE>\n"); } else { // There's a count to be had out.append("<B>Records Affected:</B> " + stmt.getUpdateCount()); } } catch (SQLException e) { out.append("</TABLE><H1>ERROR:</H1> " + e.getMessage()); }

return out.toString(); }}

Reuse example

• can reuse connection created in advance in init method

Here are just the parts that differ from previous phonebook example

public void init() throws ServletException { try { // Load (and therefore register) the Oracle Driver

Class.forName("org.gjt.mm.mysql.Driver"); // Get a Connection to the database con = DriverManager.getConnection( "jdbc:mysql://localhost/test", "bob", "justabob"); }

catch (ClassNotFoundException e) { throw new UnavailableException("Couldn't load database driver"); } catch (SQLException e) { throw new UnavailableException("Couldn't get db connection"); } } public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter();

out.println("<HTML><HEAD><TITLE>Phonebook</TITLE></HEAD>"); out.println("<BODY>"); HtmlSQLResult result = new HtmlSQLResult("SELECT NAME, EMAIL, CMT, ID FROM guestlist", con);

Adding a guest to our guestlist: the get methods calls post… this mimicks text example “OrderHandler”

• I didn’t change the message text servlet printed out• uses connection pool class

Phone lookup checks the table to verify guest added

add a guest servletpublic class AddAGuestPool extends HttpServlet { private ConnectionPool pool; public void init() throws ServletException { try { pool = new ConnectionPool("org.gjt.mm.mysql.Driver","jdbc:mysql://localhost/test", "bob", "justabob",5); }//get

connections catch (Exception e) { throw new UnavailableException("Couldn't create connection pool"); } }public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {doPost(req,res);} public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { Connection con = null; res.setContentType("text/plain"); PrintWriter out = res.getWriter(); try { con = pool.getConnection(); // Turn on transactions con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.executeUpdate("INSERT INTO guestlist(NAME,ID,EMAIL,CMT)values ('Xavier Poindexter

III','81234','Xavier@oneonta.edu','astounding salad bar')");//this would be form data con.commit(); out.println("Order successful! Thanks for your business!"); } catch (Exception e) { // Any error is grounds for rollback try {con.rollback(); } catch (Exception ignored) { } out.println("Order failed. Please contact technical support."); } finally { if (con != null) pool.returnConnection(con); } }}

Connectionpool servlet in slide notes.

• Blackscreen output (server screen) provides some information

Guestbook servlet revisited: form posts data to db…entire servlet in slide notes

Guestbook servlet revisited after pressing button (code in notes)

Guestbook servlet: some notes• Init gets a pool of connections:public void init() throws ServletException { try { ServletContext context = getServletContext(); synchronized (context) { // A pool may already be saved as a context attribute pool = (ConnectionPool) context.getAttribute("pool"); if (pool == null) { // Construct a pool using our context init parameters // connection.driver, connection.url, user, password, etc pool = new ConnectionPool(new ContextProperties(context), 3); context.setAttribute("pool", pool); } } } catch (Exception e) { throw new UnavailableException( "Failed to fetch a connection pool from the context: " + e.getMessage()); } }

Guestbook servlet: some notes• doGet and doPost are a series of method calls:public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter();

printHeader(out); printForm(out); printMessages(out); printFooter(out); }

// Add a new entry, then dispatch back to doGet() public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { handleForm(req, res); doGet(req, res); }

Guestbook servlet: some notes• Printing a form:private void printForm(PrintWriter out) { out.println("<FORM METHOD=POST>"); // posts to itself out.println("<B>Please submit your feedback:</B><BR>"); out.println("Your name: <INPUT TYPE=TEXT NAME=name><BR>"); out.println("Your email: <INPUT TYPE=TEXT NAME=email><BR>"); out.println("Comment: <INPUT TYPE=TEXT SIZE=50

NAME=comment><BR>"); out.println("<INPUT TYPE=SUBMIT VALUE=\"Send Feedback\"><BR>"); out.println("</FORM>"); out.println("<HR>"); }

HandleForm is insert record function private void handleForm(HttpServletRequest req, HttpServletResponse res) throws ServletException { String name = req.getParameter("name"); String email = req.getParameter("email"); String comment = req.getParameter("comment"); Connection con = null; PreparedStatement pstmt = null; try { con = pool.getConnection(); // Use a prepared statement for automatic string escaping pstmt = con.prepareStatement(INSERT); long time = System.currentTimeMillis(); pstmt.setString(1, Long.toString(time)); pstmt.setString(2, name); pstmt.setString(3, email); pstmt.setString(4, comment); pstmt.executeUpdate(); } catch (SQLException e) { throw new ServletException(e); } finally { try { if (pstmt != null) pstmt.close(); } catch (SQLException ignored) { } pool.returnConnection(con); }

// Make note we have a new last modified time lastModified = System.currentTimeMillis(); }

printMessages method provides Read functionality

private void printMessages(PrintWriter out) throws ServletException { String name, email, comment; Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = pool.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery(SELECT_ALL); while (rs.next()) { name = rs.getString(1); if (rs.wasNull() || name.length() == 0) name = "Unknown user"; email = rs.getString(2); if (rs.wasNull() || email.length() == 0) name = "Unknown email"; comment = rs.getString(3); if (rs.wasNull() || comment.length() == 0) name = "No comment"; out.println("<DL>"); out.println("<DT><B>" + name + "</B> (" + email + ") says"); out.println("<DD><PRE>" + comment + "</PRE>"); out.println("</DL>"); } } catch (SQLException e) { throw new ServletException(e); } finally { try { if (stmt != null) stmt.close(); } catch (SQLException ignored) { } pool.returnConnection(con); } }

doGet/doPost

• Updates, inserts and delets should call doPost method

• Select (read) should call doGet

Deleting a record… entire servlet in notes

…omitted imports and init which makes connection//Process the HTTP Post request public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = new PrintWriter (response.getOutputStream()); Statement stmt=null; String query=""; out.println("<html>"); out.println("<head><title>Servlet</title></head>"); out.println("<body>");try { stmt = con.createStatement (); String name = request.getParameter("name"); query="DELETE from table1 where name='" + name+"'"; out.println("Query: "+query+"<BR>"); int count=stmt.executeUpdate( query ); out.println("modified records ="+count); }catch (SQLException e2) { System.out.println("SQLException: "+e2); }finally{ out.println("</body></html>"); out.close();} }

Deleting a record…continued

//Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse

response) throws ServletException, IOException { PrintWriter out = new PrintWriter (response.getOutputStream()); out.println("<html>"); out.println("<head><title>Servlet</title></head>"); out.println("<body>"); out.println("servlet does not support get"); out.println("</body></html>"); out.close(); }}

Context parameters in web.xml for guestbook connection

<!-- info to init db connection --> <context-param> <param-name> connection.driver </param-name> <param-value> org.gjt.mm.mysql.Driver </param-value> </context-param> <context-param> <param-name> connection.url </param-name> <param-value> jdbc:mysql://localhost/test </param-value> </context-param><context-param> <param-name> user </param-name> <param-value> bob </param-value> </context-param> <context-param> <param-name> password </param-name> <param-value> justabob </param-value> </context-param>

Recommended