An Introduction to XML and Web Technologies
Programming Web Applications with Servlets ith S l t
Anders Mller & Michael I. Schwartzbach 2006 Addison Wesley Addison-Wesley
Objectives
How to program Web applications using servlets Advanced concepts such as listeners filters and concepts, listeners, filters, request dispatchers Running servlets using the Tomcat server
An Introduction to XML and Web Technologies
Web Applications
Web servers
return files run programs
Web application: collection of servlets, JSP pages, HTML pages, GIF files, ... Servlets: programmed using the servlet API API, which is directly based on HTTP Lifecycles
application session i t interaction ti (shared state) (session state) (transient state) (t i t t t )
3
An Introduction to XML and Web Technologies
An Example Servlet
import [Link].*; p j ; import [Link].*; import [Link].*; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) l ) throws IOException, ServletException { p yp ; [Link]("text/html"); PrintWriter out = [Link](); [Link]("<html><head><title>ServletExample</title></head>"+ <body><h1>Hello World!</h1>"+ "<body><h1>Hello World!</h1> + "This page was last updated: "+ new [Link]()+ "</body></html>"); } }
An Introduction to XML and Web Technologies
Requests
Methods in HttpServletRequest
getHeader getParameter getInputStream getRemoteHost, getRemoteAddr, getRemotePort tR t H t tR t Add tR t P t ...
An Introduction to XML and Web Technologies
Example: HttpServletRequest (1/2)
public class Requests extends HttpServlet { public oid doGet(HttpSer letReq est req est p blic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { [Link]("text/html"); PrintWriter out = [Link](); [Link]("<html><head><title>Requests</title></head><body>"); [Link]("<h1>Hello, visitor from "+[Link]()+"</h1>"); String useragent = [Link]("User-Agent"); if (useragent!=null) (useragent! null) [Link]("You seem to be using "+useragent+"<p>"); String name = [Link]("name"); if (name null) (name==null) [Link]("No <tt>name</tt> field was given!"); else [Link]("The value of the <tt>name</tt> fi ld is: <tt>" + i l (" h l f h / field i " htmlEscape(name) + "</tt>"); [Link]("</body></html>"); }
An Introduction to XML and Web Technologies
Example: HttpServletRequest (2/2)
public void doPost(HttpServletRequest request, HttpServletResponse HttpSer letResponse response) throws IOException, ServletException { doGet(request, response); } private String htmlEscape(String s) { StringBuffer b = new StringBuffer(); for (int i = 0; i<[Link](); i++) { char c = [Link](i); switch (c) { it h ( ) case '<': [Link]("<"); break; case '>': [Link](">"); break; case '"': [Link]("""); break; case '\'': [Link]("'"); break; case '&': [Link]("&"); break; default: [Link](c); } } return [Link](); } }
An Introduction to XML and Web Technologies
Responses
Methods in HttpServletResponse
setStatus addHeader, addHeader setHeader getOutputStream, getWriter setContentType tC t tT sendError, sendRedirect ...
An Introduction to XML and Web Technologies
Example: BusinessCardServlet
public class BusinessCardServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { p yp ; ; [Link]("text/xml;charset=UTF-8"); long expires = new Date().getTime() + 1000*60*60*24; [Link]("Expires", expires); XMLOutputter outputter = new XMLOutputter(); [Link](getBusinessCard(), [Link]()); response getOutputStream()); } ... using JDOM to generate an XML document with a reference to an XSLT stylesheet
9
An Introduction to XML and Web Technologies
Servlet Contexts
One ServletContext object for each Web application getServerInfo getInitParameter ... Shared state:
setAttribute(name, value) getAttribute(name) getAttribute( ) dont use for mission critical data! don t
An Introduction to XML and Web Technologies
10
Example: A Polling Service
A Web application consisting of
[Link] [Link] Q i kP llS t j [Link] [Link] Q [Link] j
An Introduction to XML and Web Technologies
11
Example: Example: [Link]
<html> <head><title>QuickPoll</title></head> <body> <h1>QuickPoll</h1> <form method=post action=setup> p p What is your question?<br> <input name=question type=text size=40>?<br> <input type=submit name=submit value="Register my question"> </form> </body> </html>
An Introduction to XML and Web Technologies
12
Example: Example: [Link]
p public class Q QuickPollSetup extends HttpServlet { p p public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { IOException String q = [Link]("question"); ServletContext c = getServletContext(); [Link]("question", q); [Link]("yes", new Integer(0)); [Link]( no c setAttribute("no", new Integer(0)); [Link]("text/html"); PrintWriter out = [Link](); [Link]("<html><head><title>QuickPoll</title></head><body>"+ i (" h l h d i l i k ll / i l /h d b d " "<h1>QuickPoll</h1>"+ q g "Your question has been registered. "+ "Let the vote begin!"+ "</body></html>"); } }
An Introduction to XML and Web Technologies
13
Example: [Link]
public class QuickPollAsk extends HttpServlet { public void d bli id doGet(HttpServletRequest request, ( l HttpServletResponse response) throws IOException, ServletException { [Link]("text/html"); PrintWriter out = [Link](); [Link]( <html><head><title>QuickPoll</title></head><body> + out print("<html><head><title>QuickPoll</title></head><body>"+ "<h1>QuickPoll</h1>"+ "<form method=post action=vote>"); String question = (String)getServletContext().getAttribute("question"); [Link](question+ ?<p> ); [Link](question+"?<p>"); [Link]("<input name=vote type=radio value=yes> yes<br>"+ "<input name=vote type=radio value=no> no<p>"+ "<input type=submit name=submit value=Vote>"+ " i b i b i l " "</form>"+ "</body></html>"); } }
An Introduction to XML and Web Technologies
14
Example: [Link] (1/2)
p public class QuickPollVote extends HttpServlet { Q p public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String vote = [Link]("vote"); ServletContext c = getServletContext(); if ([Link]("yes")) { int yes = ((Integer)[Link]("yes")).intValue(); yes++; [Link]("yes", new Integer(yes)); } else if ([Link]( no )) { (vote equals("no")) int no = ((Integer)[Link]("no")).intValue(); no++; [Link]("no", new Integer(no)); }
An Introduction to XML and Web Technologies
15
Example: [Link] (2/2)
[Link]("text/html"); p yp ( / ); PrintWriter out = [Link](); [Link]("<html><head><title>QuickPoll</title></head><body>"+ "<h1>QuickPoll</h1>"+ "Thank you for your vote!"+ "</body></html>"); </body></html> ); } }
An Introduction to XML and Web Technologies
16
Example: [Link] (1/2)
p public class QuickPollResults extends HttpServlet { Q p public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ServletContext c = getServletContext(); String question = (String)[Link]("question"); (String)[Link]( question ); int yes = ((Integer)[Link]("yes")).intValue(); int no = ((Integer)[Link]("no")).intValue(); int total = yes+no; [Link]("text/html"); [Link]( Expires response setDateHeader("Expires", 0); [Link]("Cache-Control", "no-store, no-cache, must-revalidate"); [Link]("Pragma", "no-cache"); PrintWriter out = [Link]();
An Introduction to XML and Web Technologies
17
Example: [Link] (2/2)
[Link]("<html><head><title>QuickPoll</title></head><body>"+ p ( Q / / y "<h1>QuickPoll</h1>"); if (total==0) [Link]("No votes yet..."); else { [Link](question + "?<p>"+"<table border 0> + ?<p> + <table border=0>"+ "<tr><td>Yes:<td>"+drawBar(300*yes/total)+"<td>"+yes+ "<tr><td>No:<td>"+drawBar(300*no/total)+"<td>"+no+ "</table>"); } [Link]( </body></html> ); out print("</body></html>"); } String drawBar(int length) { return "<table><tr><td bgcolor=black height=20 width="+ length+"></table>"; } }
An Introduction to XML and Web Technologies
18
Problems in QuickPoll
Need access control to QuickPollSetup No escaping of special characters Need to check right order of execution Need to check that expected form field data is present No synchronization in QuickPollVote Should store state in database Redundancy in HTML generation
An Introduction to XML and Web Technologies
19
Example: Shopping Cart
An Introduction to XML and Web Technologies
20
Sessions
One HttpSession object for each session
obtained by getSession in the HttpServletRequest object Htt S l tR t bj t
Session state:
setAttribute(name, value) setAttribute( getAttribute(name)
Hides the technical details of tracking users with URL rewriting / cookies / SSL sessions
An Introduction to XML and Web Technologies
21
Web Applications
A Web app is structured as a directory: myapp/ contains HTML/CSS/GIF/... files myapp/WEB-INF/ /WEB INF/ contains the deployment descriptor [Link] myapp/ /WEB-INF/classes/ / l / contains servlet class files (in subdirs corresponding to package names) myapp/WEB-INF/lib/ /WEB INF/lib/ contains extra jar files
An Introduction to XML and Web Technologies
22
Deployment Descriptors
An XML file web xml describing [Link] mapping from URIs to application resources initialization parameters security constraints registration of listeners and filters
An Introduction to XML and Web Technologies
23
Example [Link]
<web app xmlns="[Link] <web-app xmlns [Link] version="2.4"> <display-name>A Small Web Application</display-name> di l A S ll W b A li ti /di l <servlet> <servlet-name>MyFirstServlet</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet mapping> <servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> p / / / p <url-pattern>/hello/*</url-pattern> </servlet-mapping> </web-app> / b
An Introduction to XML and Web Technologies
24
The Tomcat Server
Reference Implementation, Open Source Implementation common/lib/[Link] bin/[Link], bin/[Link] conf/[Link] webapps/myapp
An Introduction to XML and Web Technologies
25
Advanced Features Listeners Filters and wrappers Request dispatchers R t di t h Security
An Introduction to XML and Web Technologies
26
Listeners
also called observers or event handlers ServletContextListener Web application initialized / shut down ServletRequestListener request handler starting / finishing HttpSessionListener session created / invalidated ServletContextAttributeListener context attribute added / removed / replaced HttpSessionAttributeListener session attribute added / removed / replaced
An Introduction to XML and Web Technologies
27
Example: SessionMonitor (1/2)
import [Link].*; import [Link].*; public class SessionMonitor implements HttpSessionListener, ServletContextListener { private int active = 0, max = 0; public void contextInitialized(ServletContextEvent sce) { store([Link]()); } public void contextDestroyed(ServletContextEvent sce) {} public void sessionCreated(HttpSessionEvent se) { active++; if (active>max) max = active; store([Link]().getServletContext()); }
An Introduction to XML and Web Technologies
28
Example: SessionMonitor (2/2)
public void sessionDestroyed(HttpSessionEvent se) { active--; store([Link]().getServletContext()); } private void store(ServletContext c) { [Link]( sessions_active c setAttribute("sessions active", new Integer(active)); [Link]("sessions_max", new Integer(max)); } }
Registration in [Link]:
<listener> <listener-class>SessionMonitor</listener-class> <listener>
An Introduction to XML and Web Technologies
29
Filters
Code being executed before and after the servlet
executed in stack-like fashion with servlet at the bottom
Can intercept and redirect processing
security auditing
Can C modify requests and responses dif t d
data conversion (XSLT, gzip, ...) specialized caching
all without changing the existing servlet code!
An Introduction to XML and Web Technologies
30
Example: LoggingFilter (1/2)
import [Link].*; import [Link].*; import [Link].*; public class LoggingFilter implements Filter { ServletContext context; int counter; p public void init(FilterConfig c) throws ServletException { g p context = [Link](); } public void destroy() {}
An Introduction to XML and Web Technologies
31
Example: LoggingFilter (2/2)
public void doFilter(ServletRequest request, ServletResponse response, l FilterChain chain) throws IOException, ServletException { String uri = ((HttpServletRequest)request).getRequestURI(); int n = ++counter; [Link]( starting context log("starting processing request # +n+ ("+uri+")"); #"+n+" ( +uri+ ) ); long t1 = [Link](); [Link](request, response); long t2 = [Link](); [Link]("done processing request #"+n+", "+(t2-t1)+" ms"); } }
An Introduction to XML and Web Technologies
32
Registration of Filters in [Link]
<web-app ...> b ... <filter> <filter-name>My Logging Filter</filter-name> <filter-class>LoggingFilter</filter-class> </filter> <filter-mapping> fil i <filter-name>My Logging Filter</filter-name> <url-pattern>/ </url-pattern> <url-pattern>/*</url-pattern> </filter-mapping> ... </web-app>
An Introduction to XML and Web Technologies
33
Wrappers
Used by filters to modify requests and responses
HttpServletRequestWrapper HttpServletResponseWrapper Example: performing server-side XSLT transformation for older browsers f f
An Introduction to XML and Web Technologies
34
Example: XSLTFilter (1/5)
import import import import import import import i import [Link].*; [Link].*; [Link].*; [Link]. ; [Link].*; [Link].*; [Link].*; [Link].*; jd i * [Link].*;
public class XSLTFilter implements Filter { ServletContext context; public void init(FilterConfig c) throws ServletException { context = [Link](); } public void destroy() {}
An Introduction to XML and Web Technologies
35
Example: XSLTFilter (2/5)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest hreq = (HttpServletRequest)request; HttpServletResponse hresp = (HttpServletResponse)response; boolean client_capable = b l li bl checkXSLTSupport([Link]("User-Agent")); p ; ServletResponse res; if (client_capable) res = response; else res = new BufferingResponseWrapper(hresp); [Link](request, res);
An Introduction to XML and Web Technologies
36
Example: XSLTFilter (3/5)
if (!client_capable) { try { [Link]("application/xhtml+xml"); transform(((BufferingResponseWrapper)res).getReader(), [Link]()); } catch (Throwable e) { [Link]("XSLT transformation error", e); [Link](500, "XSLT transformation error"); } } } boolean checkXSLTSupport(String user_agent) { if (user_agent==null) return false; return user_agent.indexOf("MSIE 5.5")!=-1 || user_agent.indexOf("MSIE 6")!=-1 || user_agent.indexOf("Gecko")!=-1; }
An Introduction to XML and Web Technologies
37
Example: XSLTFilter (4/5)
void transform(Reader in, Writer out) throws JDOMException, IOException { [Link]("[Link]", [Link] ); "[Link]"); SAXBuilder b = new SAXBuilder(); Document d = [Link](in); List pi = [Link](new [Link] i i d ( jd fil il ([Link])); g g p g String xsl = ((ProcessingInstruction)([Link](0))) .getPseudoAttributeValue("href"); XSLTransformer t = new XSLTransformer(xsl); Document h = [Link](d); t transform(d); (new XMLOutputter()).output(h, out); } }
An Introduction to XML and Web Technologies
38
Example: XSLTFilter (5/5)
class BufferingResponseWrapper extends HttpServletResponseWrapper { CharArrayWriter buffer; PrintWriter writer; public BufferingResponseWrapper(HttpServletResponse res) { super(res); buffer = new CharArrayWriter(); writer = new PrintWriter(buffer); } public PrintWriter getWriter() { return writer; } Reader getReader() { g () return new CharArrayReader([Link]()); } }
An Introduction to XML and Web Technologies
39
Request Dispatchers
Forwarding requests to other resources Often used with JSP...
An Introduction to XML and Web Technologies
40
Security Roles and Authentication
<web-app ...> b ... <security role> <security-role> <role-name>administrator</role-name> <role-name>teacher</role-name> <role-name>student</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> <realm-name>Administration</realm-name> g g </login-config> ... </web-app>
An Introduction to XML and Web Technologies
41
Security Constraints
... <security-constraint> <web-resource-collection> <web-resource-name>Restricted Area</web resource name> <web resource name>Restricted Area</web-resource-name> <url-pattern>/restricted/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth constraint> <auth-constraint> <role-name>administrator</role-name> <role-name>teacher</role-name> </auth-constraint> / h i <user-data-constraint> p g / p g <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> ...
An Introduction to XML and Web Technologies
42
Programmatic Security
Useful request methods:
getRemoteUser() isUserInRole(String role) isSecure() getAuthType() getAttribute([Link].X509Certificate)
An Introduction to XML and Web Technologies
43
Summary
Servlets closely follow the request response request-response pattern from HTTP Features:
Multi-threading Declarative configuration Request parsing, including decoding of form data Shared state Session management Advanced code structuring: listeners, filters, wrappers Client authentication, SSL
44
An Introduction to XML and Web Technologies
Essential Online Resources The servlet API:
[Link] 5 5 d / l t i/
Sun's home page for servlets:
[Link] [Link] sun com/products/servlet/
The Tomcat server:
[Link] p //j p g/ /
An Introduction to XML and Web Technologies
45
Limitations of Servlets
Low-level Low level construction of HTML documents
fragments (strings) written to output stream no static well-formedness/validity guarantees
Low-level session management
control-flow i often unclear t l fl is ft l no enforcement of relation between showing a page and receiving form input primitive session state management
An Introduction to XML and Web Technologies
46
JWIG
Research project ([Link] jwig org/) ([Link] Session threads
showing a page and receiving form input modeled as a Remote Procedure Call (RPC)
explicit control-flow simpler session state management
Template-based page construction using XACT p p g g Static checking of
output validity form field consistency
An Introduction to XML and Web Technologies
47
Example: The Guessing Game in JWIG
An Introduction to XML and Web Technologies
48
[Link]
<html> <head><title>The Guessing Game</title></head> <body bgcolor="aqua"><[BODY]></body> </html>
An Introduction to XML and Web Technologies
49
GuessingGame (1/5)
import import import import import import [Link].*; [Link].*; [Link].*; [Link]. ; [Link].*; [Link].*; [Link].*;
public class GuessingGamePlay extends SessionThread { p public XML main() throws IOException, ServletException { p , p XML wrapper = [Link]("[Link]"); XML form = [[ <form><input name="guess" type "text" size "2" maxlength "2"/> name guess type= text size= 2 maxlength= 2 /> <input type="submit" name="continue" value="continue"/></form> ]];
An Introduction to XML and Web Technologies
50
GuessingGame (2/5)
ServletContext c = getServletContext(); Integer plays = (Integer)[Link]("plays"); if (plays null) (plays==null) plays = new Integer(0); else plays = new Integer([Link]()+1); l ( l i l () 1) [Link]("plays", plays); int number = (new Random()).nextInt(100)+1; show([Link]("BODY", [[Please guess a number between 1 and 100: <{form}>]]));
An Introduction to XML and Web Technologies
51
GuessingGame (3/5)
int guesses = 1; boolean done = false; while (!done) { int guess = [Link](getParameter("guess")); if (guess==number) done = true; else { pp p g show([Link]("BODY", [[ That is not correct. Try a <b><{(guess>number)?"lower":"higher"}></b> number: <{form}> ]])); guesses++; } }
An Introduction to XML and Web Technologies
52
GuessingGame (4/5)
XML msg = [[You got it, using <b><{guesses}></b> guesses.]]; XML thanks = [[Thank you for playing this exciting game!]]; XML res; if (guesses<getCurrentRecord()) { show([Link]("BODY", [[ ( pp p g( , <{msg}><p/> That makes you the new record holder!<p/> Please enter your name for the hi-score list: <form><input name="name" type="text" size="20"/> <input type="submit" name="continue" value="continue"/></form> ]])); synchronized(c) { if (guesses<getCurrentRecord()) { [Link]("holder", getParameter("name")); [Link]("record", c setAttribute("record" new Integer(guesses)); } } res = [Link]( BODY , thanks); wrapper plug("BODY" } else res = [Link]("BODY", [[<{msg}><p/><{thanks}>]]); return res; ; }
An Introduction to XML and Web Technologies
53
GuessingGame (5/5)
int getCurrentRecord() { Integer record = (Integer)[Link]("record"); if (record!=null) return [Link](); else return Integer.MAX_VALUE; // no players yet } }
An Introduction to XML and Web Technologies
54
GuessingGameHiScore
public class GuessingGameHiscore extends HttpServlet { public void doGet() throws IOException, ServletException { ServletContext c = getServletContext(); Integer plays = (Integer)[Link]( plays ); (Integer)[Link]("plays"); String holder = (String)[Link]("holder"); Integer record = (Integer)[Link]("record"); XML b d body; if (record!=null) y p y g p y g , body = [[In <{[Link]()}> plays of this game, the record holder is <b><{holder}></b> with <b><{[Link]()}></b> guesses.]]; else body = [[No players yet.]]; [Link]("[Link]") .plug("BODY", body).write([Link]()); } }
An Introduction to XML and Web Technologies
55
Static Analysis of JWIG Programs
plug analysis
class files
flow graph fl h constructor
flow graph
summary graph analysis
summary graphs
receive analysis
string analysis
regular languages
show analysis
An Introduction to XML and Web Technologies
56
Catching Errors at Compile Time
... XML ask = [[ <form>Your name? <input name="NAME"/> <input type="submit"/></form> ]]; ... *** Field NAME is never available on line 15 *** Invalid XHTML at line 14 --- element input: requirement not satisfied: <or> <attribute name= type > name="type"> <union> <string value="submit" /> <string value="reset" /> value reset </union> </attribute> <attribute name="name" /> ib " " / </or>
An Introduction to XML and Web Technologies
57