The web tier servlets Notes based largely on

The web tier: servlets Notes based largely on Hunter & Crawford (2001) Java E-Commerce © Martin Cooke, 2003

Plan • • Servlet life cycle Session-management TOMCAT & ANT Applet-Servlet communication 10/31/2020 Java E-Commerce © Martin Cooke, 2003 2

The servlet life-cycle Java E-Commerce © Martin Cooke, 2003

Servlet life cycle: creation Client browser Servlet instance Web server Client browser 10/31/2020 Back-end data sources Init() called lookup initialisation parameters open shared resources - database connections - price lists, … Java E-Commerce © Martin Cooke, 2003 4

Servlet life cycle: handle request Client browser Servlet instance Web server Back-end data sources Client browser do. Get() or do. Post() called 10/31/2020 Java E-Commerce © Martin Cooke, 2003 5

Servlet life cycle: handle request Client browser Servlet instance Web server Back-end data sources Client browser do. Get() or do. Post() called 10/31/2020 Java E-Commerce © Martin Cooke, 2003 6

concurrent requests Client browser Servlet instance Web server Back-end data sources Client browser Each request handled in separate thread 10/31/2020 Java E-Commerce © Martin Cooke, 2003 7

Servlet life cycle: server shutdown Client browser Servlet instance Web server Back-end data sources Client browser destroy() called free up valuable connections save state? 10/31/2020 Java E-Commerce © Martin Cooke, 2003 8

Concurrency: a counter public class Counter extends Http. Servlet { int count = 0; public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); count++; out. println(“Accessed ”+count+ “ times since loading”); } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 9

Concurrency: a counter public class Counter extends Http. Servlet { int count = 0; public void do. Get(Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); count++; out. println(“Accessed ”+count+ “ times since loading”); Information stored in instance variables has potential for corruption: count++; // thread 1 count++; // thread 2 out. println…. // thread 1 out. println…. // thread 2 } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 10

Option 1: synchronise entire method public class Counter extends Http. Servlet { int count = 0; public synchronised void do. Get (Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { Safe but slow: one -at-a-time method invocation res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); count++; out. println(“Accessed ”+count+ “ times since loading”); } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 11

Option 2: synchronise refs to count public class Counter extends Http. Servlet { int count = 0; public synchronised void do. Get (Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); synchronized(this) { count++; out. println(“Accessed ”+count+ “ times since loading”); } } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 Faster: servlet can execute multiple do. Gets; Thread obtains a lock on synchronised code, waiting if another thread has it 12

Option 3: use local variable public class Counter extends Http. Servlet { int count = 0; public synchronised void do. Get (Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { Faster still: only one line to be locked res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); int local_count; synchronized(this) { local_count = ++count; } out. println(“Accessed ”+count+ “ times since loading”); } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 13

Option 4: live with it! public class Counter extends Http. Servlet { int count = 0; public synchronised void do. Get (Http. Servlet. Request req, Http. Servlet. Response res) throws Servlet. Exception, IOException { Does it really matter? res. set. Content. Type("text/plain"); Print. Writer out = res. get. Writer(); count++; out. println(“Accessed ”+count+ “ times since loading”); } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 14

A persistent counter public void init(Servlet. Config config) throws Servlet. Exception { super. init(config); try { // load the initial count from saved state } catch { // various possible exceptions } } public void destroy() { try { // save state } etc } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 15

Single. Thread. Model: instead of this… Client browser Servlet instance Web server Back-end data sources Client browser Each request handled in separate thread 10/31/2020 Java E-Commerce © Martin Cooke, 2003 16

Single. Thread. Model Client browser Servlet instance Client browser Web Servlet server instance Back-end data sources Each request handled in separate servlet instance Better to create pool of needed resources and synchronize code sections + Thread-safe: no need to synchronise access to instance variables - Consumes more resources - Doesn’t guarantee thread-safety for access to resources outside servlet (though JDBC Connections are thread-safe) 10/31/2020 Java E-Commerce © Martin Cooke, 2003 17

Session management Overcoming a stateless protocol Java E-Commerce © Martin Cooke, 2003

Traditional ways to track requests method what’s involved pros User Tell server to protect a set authorisation of pages, then call get. Remote. User() for each request cons Simple & robust Works even if user exits browser and restarts Requires user registration Hidden form fields <INPUT TYPE=hidden NAME=“martin” VALUE=“cooke”> Anonymous (can just send an ID) Works only forms Involves programming URL rewriting /My. Servlet? sessionid=123 /My. Servlet/123 Works for all dynamic docs Tedious to program Parameter name clashes Persistent cookies Send info to browser for later re-reading Easy & supported in Servlet API Browser ie user may not accept them; cookie attached to browser, not user 10/31/2020 Java E-Commerce © Martin Cooke, 2003 19

Java Session Tracking API • • • Avoids the need to implement session-tracking ourselves Uses one of the techniques listed (usually cookies, but we don’t have to know which, though we can find out) Simple and elegant 10/31/2020 Java E-Commerce © Martin Cooke, 2003 20

Sessions • • A session is a continuous connection from the same browser over a period of time Expires after a set time of inactivity (30 mins is usual) OR when manually invalidated by servlet 10/31/2020 Java E-Commerce © Martin Cooke, 2003 21

Session example public void do. Get(…){ res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); Http. Session session = req. get. Session(true); Integer count = (Integer) session. get. Value(“counter”); if (count == null) count = new Integer(1); else count = new Integer(count. int. Value()+1); session. put. Value(“counter”, count); out. println("<HTML><BODY>"); out. println(“you’ve visited “+ count+” times”); out. println("</BODY></HTML>"); } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 22

Session example public void do. Get(…){ res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); Http. Session session = req. get. Session(true); Integer count = (Integer) session. get. Value(“counter”); if (count == null) count = new Integer(1); else count = new Integer(count. int. Value()+1); session. put. Value(“counter”, count); out. println("<HTML><BODY>"); out. println(“you’ve visited “+ count+” times”); out. println("</BODY></HTML>"); } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 get. Session(true) Returns a new session if one doesn’t exist 23

Session example public void do. Get(…){ res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); Http. Session session = req. get. Session(true); Integer count = (Integer) session. get. Value(“counter”); if (count == null) count = new Integer(1); else count = new Integer(count. int. Value()+1); session. put. Value(“counter”, count); out. println("<HTML><BODY>"); out. println(“you’ve visited “+ count+” times”); out. println("</BODY></HTML>"); } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 Can store any nonprimitive object in the session 24

Session example public void do. Get(…){ res. set. Content. Type("text/html"); Print. Writer out = res. get. Writer(); Http. Session session = req. get. Session(true); Integer count = (Integer) session. get. Value(“counter”); if (count == null) count = new Integer(1); else count = new Integer(count. int. Value()+1); session. put. Value(“counter”, count); out. println("<HTML><BODY>"); out. println(“you’ve visited “+ count+” times”); out. println("</BODY></HTML>"); } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 Other useful methods: get. Value. Names() returns String[] invalidate() removes session and all objects contained get. Creation. Time() get. Last. Accessed. Time() 25

Session binding events • Provides a mechanism to allow servlets to listen for the creation and destruction (binding and unbinding) of sessions • Useful for e. g. allocating and closing database connections • Need class which implements Http. Session. Binding. Listener interface, with methods: – public void value. Bound(Http. Session. Binding. Event event) – public void value. Unbound(Http. Session. Binding. Event event) 10/31/2020 Java E-Commerce © Martin Cooke, 2003 26

How-to Tomcat & Ant Java E-Commerce © Martin Cooke, 2003

Tomcat • Tomcat is a free servlet (and JSP) container • Sun’s reference implementation, developed by Apache • Versions for Win, Linux, etc • Obtain from jakarta. apache. org/tomcat • Easy to install • Available in the dept: see Dept web guide • Some alternatives (eg Jetty - small footprint) 10/31/2020 Java E-Commerce © Martin Cooke, 2003 28

Installation & running • Extract • Ensure JAVA_HOME points to directory where JDK is installed • Ensure CATALINA_HOME points to directory where Tomcat was extracted • Execute the startup file in binstartup. bat (or startup. sh) • Check http: //localhost: 8080 • Ensure you have nothing else listening on port 8080. If you do, change the Tomcat port in confserver. xml 10/31/2020 Java E-Commerce © Martin Cooke, 2003 29

Web app configuration (web. xml) <servlet> <servlet-name>Controller</servlet-name> <servlet-class>shef. wtt. Controller</servlet-class> <init-param> <param-name>db. Driver</param-name> <param-value>org. gjt. mm. mysql. Driver</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Controller</servlet-name> <url-pattern>/controller</url-pattern> </servlet-mapping> <session-config> <session-timeout>120</session-timeout> </session-config> 10/31/2020 Java E-Commerce © Martin Cooke, 2003 30

Using Tomcat • Lots of beginners’ pitfalls! • Leave time to sort them out – classpath issues – Servlet visibility issues – Web application organisation • Check log files • Use logging 10/31/2020 Java E-Commerce © Martin Cooke, 2003 31

Ant • Typical (smallish) webapp has 100’s of files – Screen definitions – Event handlers – Static pages • Ant is a Java-based build tool – cf UNIX make • Uses XML • Will save you hours! 10/31/2020 Java E-Commerce © Martin Cooke, 2003 32

Example build. xml <!-- ====== Compile Target ========= --> <target name="compile" depends="prepare, xmlc" description="Compile Java sources"> <!-- Compile Java classes as necessary --> <javac srcdir="src" destdir="${build. home}/WEB-INF/classes" debug="${compile. debug}" deprecation="${compile. deprecation}" optimize="${compile. optimize}"> <classpath refid="compile. classpath"/> </javac> </target> 10/31/2020 Java E-Commerce © Martin Cooke, 2003 33

homework • Install Tomcat 4 • Install Ant • Develop your first servlet using both 10/31/2020 Java E-Commerce © Martin Cooke, 2003 34

Applet-servlet communication (if time) Java E-Commerce © Martin Cooke, 2003

Applets are sometimes useful 10/31/2020 Java E-Commerce © Martin Cooke, 2003 36

The applet problem Persistent storage Applet can only talk to its host server. But what if the database is located elsewhere? 10/31/2020 Java E-Commerce © Martin Cooke, 2003 37

A solution Web server Persistent storage Use one of many techniques for appletservlet communication - simplest is HTTP 10/31/2020 Java E-Commerce © Martin Cooke, 2003 38

How-to: send from applet Web server URLConnection con = … con. set. Do. Input(true); con. set. Do. Output(true); // further incantations Object. Output. Stream oos = new Object. Output. Stream( con. get. Output. Stream()); oos. write. Object(obj); out. flush(); out. close(); 10/31/2020 Java E-Commerce © Martin Cooke, 2003 39

How-to: receiving at the servlet Web server Object. Input. Stream ois = new Object. Input. Stream (req. get. Input. Stream()); Object obj = ois. read. Object(); 10/31/2020 Java E-Commerce © Martin Cooke, 2003 40

Filters Java E-Commerce © Martin Cooke, 2003

Filters • A filter is an object that can transform a request or modify a response • Not servlets: don’t actually create a response • Pre- or post-processors of servlets • Can be configured to act on a servlet or a group of servlets • Zero or more filters can filter one or more servlets 10/31/2020 Java E-Commerce © Martin Cooke, 2003 42

Some applications • Record duration of all requests • Track user requests and request sequences (AKA clickstreams) • Compress the response • Authentication • Logging/auditing • Image conversion • Encryption • XSLT transforming XML 10/31/2020 Java E-Commerce © Martin Cooke, 2003 43

Example filter: logging public class Log. Filter implements Filter { public void do. Filter(Servlet. Request req, Servlet. Response res, Filter. Chain chain) { Servlet. Context context = get. Filter. Config(). get. Servlet. Context(); long bef = System. current. Time. Millis(); chain. do. Filter(req, res); long aft = System. current. Time. Millis(); context. log(“Request: ”+req. get. Request. URI()+”: ”+(aft-bef)); } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 44

General model public void do. Filter(Servlet. Request req, Servlet. Response res, Filter. Chain chain) { // do something with req // e. g. check headers to see if gzip accepted chain. do. Filter(req, res); // do something with res // e. g. compress } } 10/31/2020 Java E-Commerce © Martin Cooke, 2003 45

Sending things other than HTML Java E-Commerce © Martin Cooke, 2003

Serving WAP devices • Encode application using WML • Set content type to text/vnd. wap. wml or add line like this to web. xml: – <mime-mapping> <extension>wml</extension> <mime-type>text/vnd. wap. wml</mime-type> </mime-mapping> • Test using a simulator 10/31/2020 Java E-Commerce © Martin Cooke, 2003 47

Sending images • set content type to image/gif or image/jpeg, … • send image data on Servlet. Output. Stream: – Servlet. Output. Stream out = res. get. Output. Stream(); • can generate image dynamically: – Create Image object (eg use Java 2 D or AWT or …) – Gif. Encoder encoder = new Gif. Encoder(image, out); encoder. encode(); – Can use free GIF encoder from www. acme. com: import Acme. JPM. Encoders. Gif. Encoder; • often worth compressing: – res. set. Header(“Content-Encoding”, ”gzip”); – Use Zip. Output. Stream from java. util. zip 10/31/2020 Java E-Commerce © Martin Cooke, 2003 48
- Slides: 48