Internet Technologies 6 - Servlets I F. Ricci 2010/2011 Content - - PowerPoint PPT Presentation

internet technologies 6 servlets i
SMART_READER_LITE
LIVE PREVIEW

Internet Technologies 6 - Servlets I F. Ricci 2010/2011 Content - - PowerPoint PPT Presentation

Internet Technologies 6 - Servlets I F. Ricci 2010/2011 Content Basic Servlets Tomcat Servlets lifecycle Servlets and forms Reading parameters Filtering text from HTML-specific characters Reading headers Sending


slide-1
SLIDE 1

Internet Technologies 6 - Servlets I

  • F. Ricci

2010/2011

slide-2
SLIDE 2

Content

 Basic Servlets  Tomcat  Servlets lifecycle  Servlets and forms  Reading parameters  Filtering text from HTML-specific characters  Reading headers  Sending compressed content  Differentiating among browsers  Referer Most of the slides were made available by www. coreservlets.com

slide-3
SLIDE 3

Servlet Roles

 Read the explicit data sent by the client  Read the implicit HTTP request data sent by the

browser

 Generate the results  Send the explicit data (i.e., the document) to the

client

 Send the implicit HTTP response data

slide-4
SLIDE 4

HelloWorld

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** Very simplistic servlet that generates plain text. * <P> * Taken from More Servlets and JavaServer Pages * from Prentice Hall and Sun Microsystems Press, * http://www.moreservlets.com/. * &copy; 2002 Marty Hall; may be freely used or adapted. */ public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter();

  • ut.println("Hello World");

} }

code

slide-5
SLIDE 5

Servlet Container

Servlet Architecture

Client Web Java Virtual Machine (JVM) Web Server Servlet 1 HTTP Request HTTP Response Servlet 2 Servlet n

slide-6
SLIDE 6

Installing and Running Tomcat

 Tomcat is distributed as a ZIP archive http://

tomcat.apache.org

 unzip the download file, for instance into a root-

level directory: C:\apache-tomcat-6.0.16

 To run Tomcat you'll need to tell it where to find

your J2SE SDK installation

 Set the JAVA_HOME environment variable to

C:\Program Files\Java\jdk1.6.0_04

 To run Tomcat:  open a command window  change directory to Tomcat's bin directory  Type startup

slide-7
SLIDE 7

Tomcat Directory Structure

Tomcat binaries: startup, shutdown All jar libraries: e.g. servlet-api.jar Configuration files: e.g. when you build your application in Netbeans a new file is added to indicate where is deployed (e.g., C:\apache- tomcat-6.0.16\conf \Catalina\localhost \coresjsp.xml) Directories of the web applications deployed here, possibly generated by .war files deployed here (with a web.xml file)

slide-8
SLIDE 8

Catalina Base

 Go to netbeans: tools>servers to look at these

details

slide-9
SLIDE 9

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>bob</servlet-name> <servlet-class>HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>bob</servlet-name> <url-pattern>/HelloWorld</url-pattern> </servlet-mapping> </web-app>

slide-10
SLIDE 10

Compiling and deploying

 Create a directory in \webapps called hello  Create a directory in \webapps\hello called WEB-INF and

then a subdirectory classes where to put the sources and the compiled files

 Set the classpath  C:\>set CLASSPATH=\apache-tomcat-6.0.16\common

\lib\servlet-api.jar

 Compile  C:\>javac HelloWorld.java  Deploy the web.xml file in C:\apache-

tomcat-6.0.16\webapps\hello\WEB-INF

 Or use an IDE (Netbeans) – separating sources (web

directory) and deployment (build directory).

slide-11
SLIDE 11

Starting Tomcat

 /bin/startup.bat

  • r startup.sh

 Point Browers to

http://localhost:8080 should see default page

 All the Docs are there

  • n the default page!

 Check out the

examples pages, good tutorials

slide-12
SLIDE 12

Basic Servlet Structure

 Here's the outline of a basic servlet that handles GET and

POST requests in the same way:

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SomeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); // Use "out" to send content to browser } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

slide-13
SLIDE 13

HelloWorld HTML

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloServlet2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n";

  • ut.println(docType +

"<HTML>\n" + "<HEAD><TITLE>Hello (2)</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>Hello</H1>\n" + "</BODY></HTML>"); } }

code

slide-14
SLIDE 14

Some Simple HTML-Building Utilities

public class ServletUtilities { public static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">"; public static String headWithTitle(String title) { return(DOCTYPE + "\n" + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n"); } ... }

 Don’t go overboard  Complete HTML generation packages

usually work poorly

 The JSP framework is a better solution code

slide-15
SLIDE 15

HelloServlet3: Packages and Utilities

package coreservlets; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloServlet3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Hello (3)";

  • ut.println(ServletUtilities.headWithTitle(title)+

"<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1>" + title + "</H1>\n" + "</BODY></HTML>"); } }

code

slide-16
SLIDE 16

The Servlet Life Cycle (Servlet Interface)

 init  Executed once when the servlet is first loaded

Not called for each request

 service  Called in a new thread by server for each request  Dispatches to doGet, doPost, etc.

Do not override this method!

 doGet, doPost, doXxx  Handles GET, POST, etc. requests  Override these to provide desired behavior  destroy  Called when server deletes servlet instance

Not called after each request.

javadoc

slide-17
SLIDE 17

Example of usage of init

 If a servlet get a request for a url with the http header  if-Modified-Since: Mon, 12 Nov 2010 18:00:00 GMT  It can check if something has really changed the output after

that date – if not the servlet sends back a reply:

 HTTP/1.1 304 Not Modified  And the browser shows the cashed url  The servlet must only implement the following method to

know when it has been modified the last time:

 public long getLastModified(HttpServletRequest

request)

 The app server will call it when a client requests the servlet  And will send back a result only if the page was modified

(according to the value returned by the method) after Mon, 12 Nov 2010 18:00:00 GMT

slide-18
SLIDE 18

Code

 The init method set the time the page was modified public void init() throws ServletException { // Round to nearest second (i.e, 1000 milliseconds) modTime = System.currentTimeMillis()/1000*1000; for(int i=0; i<numbers.length; i++) { numbers[i] = randomNum(); } }  An then overwrite the method that tells when the

page was modified

public long getLastModified(HttpServletRequest request) { return(modTime); }

LotteryNumbers code

slide-19
SLIDE 19

Calls to the servlet

The page was modified after 8:00:00 GMT The page was not modified after 9:00:00 GMT

slide-20
SLIDE 20

Calls to the servlet

 You can do the same experiments with a telnet

connection (e.g., using putty)

slide-21
SLIDE 21

HTML Form

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD><TITLE>A Sample Form Using GET</TITLE></HEAD> <BODY> <H2 ALIGN="CENTER">A Sample Form Using GET</H2> <FORM ACTION="http://localhost:8080/coresjp/ServletForm"> <CENTER> First name: <INPUT TYPE="TEXT" NAME="FirstName" VALUE=""><BR/> Last name: <INPUT TYPE="TEXT" NAME="LastName" VALUE=""><P> <INPUT TYPE="SUBMIT"> </CENTER> </FORM> </BODY> </HTML>

form

slide-22
SLIDE 22

Reading form data in servlets

 request.getParameter(“FirstName")  Returns URL-decoded value of first occurrence of

FirstName parameter in query string

 Works identically for GET and POST requests  Returns null if no such parameter is in query data  request.getParameterValues(“FirstName")  Returns an array of the URL-decoded values of all

  • ccurrences of FirstName parameter in query string

 Returns a one-element array if param is not repeated  Returns null if no such parameter is in the query  request.getParameterNames() or

request.getParameterMap()

 Returns Enumeration or Map of request parameters  Usually reserved for debugging.

slide-23
SLIDE 23

Reading parameters

import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class ServletForm extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter();

  • ut.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" +

"<HTML>\n" + "<HEAD><TITLE>ServletForm</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">ServletForm</H1>\n" + "<UL>\n" + "<LI><B>FirstName</B>: "+ request.getParameter("FirstName")+"\n"+ "<LI><B>LastName</B>: "+ request.getParameter("LastName")+"\n"+ "</UL>\n" + "</BODY></HTML>"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

ServletForm code

slide-24
SLIDE 24

Example: reading all parameters

getform postform

slide-25
SLIDE 25

Reading All Parameters

public class ShowParameters extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " + "Transitional//EN\">\n"; String title = "Reading All Request Parameters";

  • ut.println(docType +

"<HTML>\n" + "<HEAD><TITLE>"+title + "</TITLE></HEAD>\n"+ "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Parameter Name<TH>Parameter Value(s)");

code

slide-26
SLIDE 26

Reading All Parameters

Enumeration paramNames = request.getParameterNames(); while(paramNames.hasMoreElements()) { String paramName = (String)paramNames.nextElement();

  • ut.print("<TR><TD>" + paramName + "\n<TD>");

String[] paramValues = request.getParameterValues(paramName); if (paramValues.length == 1) { String paramValue = paramValues[0]; if (paramValue.length() == 0)

  • ut.println("<I>No Value</I>");

else

  • ut.println(paramValue);

} else {

  • ut.println("<UL>");

for(int i=0; i<paramValues.length; i++) {

  • ut.println("<LI>" + paramValues[i]);

}

  • ut.println("</UL>");

} }

  • ut.println("</TABLE>\n</BODY></HTML>");

}

slide-27
SLIDE 27

Reading All Parameters

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

slide-28
SLIDE 28

Filtering Strings for HTML-Specific Chars

 You cannot safely insert arbitrary strings into servlet

  • utput

 < and > can cause problems anywhere  & and " can cause problems inside of HTML

attributes

 You sometimes cannot manually translate  The string is derived from a program excerpt or

another source where it is already in some standard format

 The string is derived from HTML form data  Failing to filter special characters from form data

makes you vulnerable to cross-site scripting attack.

slide-29
SLIDE 29

Filtering Strings for HTML-Specific Chars

public class ServletUtilities { public static String filter(String input) { if (!hasSpecialChars(input)) { return(input); } StringBuffer filtered = new StringBuffer(input.length()); char c; for(int i=0; i<input.length(); i++) { c = input.charAt(i); switch(c) { case '<': filtered.append("&lt;"); break; case '>': filtered.append("&gt;"); break; case '"': filtered.append("&quot;"); break; case '&': filtered.append("&amp;"); break; default: filtered.append(c); } } return(filtered.toString()); } …

code

slide-30
SLIDE 30

No Filtering

public class BadCodeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { …

  • ut.println(docType +

"<HTML>\n" + "<HEAD><TITLE>"+title+"</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n"+ "<PRE>\n" + getCode(request) + "</PRE>\n" + "Now, wasn't that an interesting sample\n" + "of code?\n" + "</BODY></HTML>"); } protected String getCode(HttpServletRequest request) { return(request.getParameter("code")); } }

code Spaces and line breaks are preserved

slide-31
SLIDE 31

Special Chars: no filtering

form calling the badservlet

slide-32
SLIDE 32

Servlet that does Filtering

public class GoodCodeServlet extends BadCodeServlet { protected String getCode(HttpServletRequest request) { return (ServletUtilities.filter(super.getCode(request))); //get the code as in the super class and then do the filter } }

code

slide-33
SLIDE 33

Filtering

goodservlet

slide-34
SLIDE 34

A Typical HTTP Request

GET /servlet/Search?keywords=servlets+jsp HTTP/1.1 Accept: image/gif, image/jpg, */* Accept-Encoding: gzip Connection: Keep-Alive Cookie: userID=id456578 Host: www.somebookstore.com Referer: http://www.somebookstore.com/findbooks.html User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)

 You need to understand HTTP to be effective with

servlets and JSP

slide-35
SLIDE 35

Reading Request Headers

 General methods of the HttpServletRequest  getHeader(String name) the first one with that name  getHeaders(String name) all occurrences of the header  getHeaderNames  Specialized methods of the HttpServletRequest  getCookies  getAuthType and getRemoteUser  getContentLength  getContentType  getDateHeader  getIntHeader  Related info  getMethod, getRequestURI , getQueryString,

getProtocol

slide-36
SLIDE 36

Checking For Missing Headers

 HTTP 1.0  All request headers are optional  HTTP 1.1  Only Host is required  Conclusion  Always check that request.getHeader is

non-null before trying to use it String val = request.getHeader("Some- Name"); if (val != null) { … }

slide-37
SLIDE 37

All Request Headers (Firefox)

Call servlet

slide-38
SLIDE 38

Request Headers (Internet Explorer)

slide-39
SLIDE 39

Making a Table of Request Headers

public class ShowRequestHeaders extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  • ut.println

(docType + "<HTML>\n" + "<HEAD><TITLE>"+title+"</TITLE></HEAD>\n"+ "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n" + "<B>Request Method: </B>" + request.getMethod() + "<BR>\n" + "<B>Request URI: </B>" + request.getRequestURI() + "<BR>\n" + "<B>Request Protocol: </B>" + request.getProtocol() + "<BR><BR>\n" +

code

slide-40
SLIDE 40

Request Headers (Continued)

"<TABLE BORDER=1 ALIGN=\"CENTER\">\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Header Name<TH>Header Value"); Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement();

  • ut.println("<TR><TD>" + headerName);
  • ut.println(" <TD>"+request.getHeader(headerName));

}

  • ut.println("</TABLE>\n</BODY></HTML>");

} /** Since this servlet is for debugging, have it * handle GET and POST identically. */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

slide-41
SLIDE 41

Common HTTP 1.1 Request Headers

 Accept  Indicates MIME types browser can handle  Can send different content to different clients. For

example, PNG files have good compression characteristics but are not widely supported in

  • browsers. A servlet could check to see if PNG is

supported, sending <IMG SRC="picture.png" ...> if it is supported, and <IMG SRC="picture.gif" ...> if not.

 Accept-Encoding  Indicates encodings (e.g., gzip or compress)

browser can handle.

 See following example

slide-42
SLIDE 42

Common HTTP 1.1 Request Headers

 Authorization  User identification for password-protected

pages

 Instead of HTTP authorization, use HTML forms

to send username/password and store info in session object - this approach is usually preferable because standard HTTP authorization results in a small, terse dialog box that is unfamiliar to many users

 Servers have high-level way to set up

password-protected pages without explicit programming in the servlets.

slide-43
SLIDE 43

Common HTTP 1.1 Request Headers

 Connection  In HTTP 1.0, keep-alive means browser can

handle persistent connection - in HTTP 1.1, persistent connection is default

 Persistent connections mean that the web

server can reuse the same socket over again for requests very close together from the same client (e.g., the images associated with a page,

  • r cells within a framed page).

 Servlets can't do this unilaterally; the best

they can do is to give the web server enough info to permit persistent connections - they should set Content-Length response header.

slide-44
SLIDE 44

Common HTTP 1.1 Request Headers

 Cookie

 Gives cookies previously sent to client  Use getCookies, not getHeader (we shall do

that in a next lecture)

 Host  Indicates host given in original URL  This is a required header in HTTP 1.1  This fact is important to know if you write a

custom HTTP client (e.g., WebClient we used before) or telnet to a server and use the HTTP/1.1 version.

slide-45
SLIDE 45

Common HTTP 1.1 Request Headers

 If-Modified-Since  Indicates client wants page only if it has been changed

after specified date

 Don’t handle this situation directly; implement

getLastModified instead

 See lottery-number example we have already shown  Referer  URL of referring Web page  Useful for tracking traffic; logged by many servers  Can also be used to let users set preferences and then

return to the page they came from

 Can be easily spoofed; don't let this header be sole

means of deciding how much to pay sites that show your banner ads

 Some browsers (Opera), ad filters (Web Washer), and

personal firewalls (Norton) screen out this header.

slide-46
SLIDE 46

Common HTTP 1.1 Request Headers

 User-Agent  Best used for identifying category of client

 Web browser vs. I-mode cell phone, etc.

 For Web applications, use other parameters if

possible

 Again, can be easily spoofed  We shall touch this later

slide-47
SLIDE 47

Sending Compressed Web Pages

Dilbert used with permission of United Syndicates Inc.

slide-48
SLIDE 48

Sending Compressed Pages: GzipUtilities.java

public class GzipUtilities { public static boolean isGzipSupported (HttpServletRequest request) { String encodings = request.getHeader("Accept-Encoding"); return((encodings != null) && (encodings.indexOf("gzip") != -1)); } public static boolean isGzipDisabled (HttpServletRequest request) { String flag = request.getParameter("disableGzip"); return((flag != null)&& // if the parameter is not null (!flag.equalsIgnoreCase("false"))); // and not "false" } public static PrintWriter getGzipWriter (HttpServletResponse response) throws IOException { return(new PrintWriter (new GZIPOutputStream (response.getOutputStream()))); } }

code

slide-49
SLIDE 49

Sending Compressed Pages: LongServlet.java

public class LongServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); // Change the definition of "out" depending on // whether or not gzip is supported. PrintWriter out; if (GzipUtilities.isGzipSupported(request) && !GzipUtilities.isGzipDisabled(request)) {

  • ut = GzipUtilities.getGzipWriter(response);

response.setHeader("Content-Encoding", "gzip"); } else {

  • ut = response.getWriter();

}

code

slide-50
SLIDE 50

Sending Compressed Pages: LongServlet.java

  • ut.println

(docType + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n"); String line = "Blah, blah, blah, blah, blah. " + "Yadda, yadda, yadda, yadda."; for(int i=0; i<10000; i++) {

  • ut.println(line);

}

  • ut.println("</BODY></HTML>");
  • ut.close();

} }

slide-51
SLIDE 51

Sending Compressed Pages: Results

 Uncompressed (28.8K modem),

Firefox, Netscape and Internet Explorer: > 50 seconds

 Compressed (28.8K modem),

Firefox, Netscape and Internet Explorer: < 5 seconds

 Caution:

be careful about generalizing benchmarks

call call

slide-52
SLIDE 52

Differentiating Among Different Browser Types

 Use User-Agent only when necessary  Otherwise, you will have difficult-to-maintain code that

consists of tables of browser versions and associated capabilities

 Check for null  The header is not required by the HTTP 1.1 specification,

some browsers let you disable it (e.g., Opera), and custom clients (e.g., Web spiders or link verifiers) might not use the header at all

 To differentiate among Firefox, Netscape, and Internet

Explorer, check for “MSIE,” not “Mozilla”

 Both Firefox and Internet Explorer say “Mozilla” at the

beginning of the header

 Note that the header can be faked  If a client fakes this header, the servlet cannot tell the

difference.

slide-53
SLIDE 53

Differentiating Among Different Browser Types

public class BrowserInsult extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title, message; // Assume for simplicity that Firefox and IE are // the only two browsers. String userAgent = request.getHeader("User-Agent"); if ((userAgent != null) && (userAgent.indexOf("MSIE") != -1)) { title = "Microsoft Minion"; message = "Welcome, O spineless slave to the " + "mighty empire."; } else { title = "Hopeless Firefox Rebel"; message = "Enjoy it while you can. " + "You <I>will</I> be assimilated!"; }

code

slide-54
SLIDE 54

Differentiating Among Browser Types (Result)

call

slide-55
SLIDE 55

Referer

 The Referer header designates the location of

the page users were on when they clicked on a link

 No Referer is set if the user typed the address of

the page

 You can customize a page depending on how the

user reached it

 Customize the layout of a page according to

the site that link to

 Change the content if the user come from the

same domain or another domain

 Supply a link to go back  Track the effectiveness of a banner or a link.