ibm labs in haifa dynamic web programming with servlets gal shachor

56
IBM Labs in Haifa Dynamic Web programming with Servlets Gal Shachor

Post on 22-Dec-2015

228 views

Category:

Documents


0 download

TRANSCRIPT

IBM Labs in Haifa

Dynamic Web programming with Servlets

Gal Shachor

IBM Labs in Haifa

2

Agenda

Servlets – What and Why? My first servlet The Servlet API Form processing Session state We did not talk about…

IBM Labs in Haifa

Servlets

What are they? Why do we need them

IBM Labs in Haifa

4

What Are Servlets Anyway?

A Servlet is a Java class that extends the web server's service capabilities.

When the client sends a request to the server the. Server can forward the request to a Servlet and let it handle the request.

Servlets provide open, cross-server and OS APIs. Servlets have a clean design; This leads to simplicity. Servlets live inside a Servlet Container.

IBM Labs in Haifa

5

What Is a Servlet Container

Sometimes called a Servlet Engine. Similar to what an OS is for processes The Servlet Container provides Servlets with the environment,

configuration and runtime needed to support the Servlet APIs: Load the Servlets. Initialize the Servlets. Execute the Servlets. Destroy the Servlets.

Servlets do not have a main… The container have it…

IBM Labs in Haifa

6

Who Backs Servlets?

Servlets are backed by "anybody but Microsoft." There is Servlets support for virtually all common servers (including

Microsoft's). Supporting Servlets can be done in one of two ways:

Supporting the Servlet APIs in the web-server level Adding a Servlet-Container add-on to the web-server.

IBM Labs in Haifa

7

Why Servlets?

Because we needed them!

Servlets where invented on 1996. Back then the competing technologies where: CGI – Too slow, not scalable in any important aspect Server APIs – Too complex Microsoft ASP – Beta version, slow, only NT Live wire – Only Netscape servers

The community needed a cross-server, cross-platform web server API => Servlets where invented Huge success

IBM Labs in Haifa

My first servlet

Hello World

IBM Labs in Haifa

9

HelloWorld Servlet – The code

package com.hrl.sample;

import java.io.*;

import javax.servlet.ServletException;

import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

resp.setContentType("text/html");

final PrintWriter out = resp.getWriter();

out.println("<html><body>");

out.println("<h1>Hello World (With Servlet Accent)</h1>");

out.println("</body></html>");

}

}

IBM Labs in Haifa

10

HelloWorld Servlet – Output

HTTP/1.1 200 OK

Server: WebSphere Application Server/5.0

Content-Type: text/html

Content-Language: iw-IL

Connection: close

<html><body>

<h1>Hello World (With Servlet Accent)</h1>

</body></html>

IBM Labs in Haifa

11

HelloWorld Servlet – Observations

The Servlet class extends the base class HttpServlet In a short while we will see that HttpServlet is a base class for

practically all servlets

The servlet logic is implemented in a method named doGet() Handles the HTTP GET method doPost, doHead… are also available Called from the service method To be discussed soon

IBM Labs in Haifa

12

HelloWorld Servlet – Observations

The Servlet uses request and response objects when serving a users’ request HTTP (and as a result also HTTP Servlets) follows the request-

response paradigm The HTTP request and response objects are encapsulated by a

matching Java objects

The Servlet outputs raw HTML content Generates it on the fly

The Servlet manipulates the HTTP headers But the container adds some more

IBM Labs in Haifa

The Servlet API

IBM Labs in Haifa

14

The Servlet APIs (Cont.)

Several versions: 1.0 – initial supported version (mid 1997). 2.0 – First "real" version (beginning of 1998). 2.1 – Mostly fixes and refinements for 2.0 (January, 1999) but also

preliminary application services. 2.2 – Important version (December 1999) with application definitions. 2.3 – Listeners and Filters were added. This is the version that we are

learning. 2.4 – The future

IBM Labs in Haifa

15

What’s in the APIs

The Servlet APIs defines: A servlet lifecycle – how a servlet is created, used and destroyed. A programmer interface – how a servlet looks like to the container

and how the container looks like to the servlet.

The Servlet APIs is what the programmer should care about

IBM Labs in Haifa

The Servlet Lifecycle

IBM Labs in Haifa

17

The Servlet Life-Cycle

The Servlet life-cycle defines: How a Servlet is initialized. How a Servlet is serving users and how many times. How a Servlet is destroyed. Concurrency management (multi-threading considerations).

IBM Labs in Haifa

18

Servlet Instantiation

The container instantiates a new Servlet in two occasions: A user request service from a Servlet that was not

instantiated yet. The Servlet is in the list of startup Servlets and the container

is starting.

A Servlet is instantiated in the following manner: The container loads the Servlet’s class. Using Class.newInstance() the container instantiates a new

instance of the Servlet.

IBM Labs in Haifa

19

Servlet Initialization

After the instantiation, the container initializes the Servlet. The container casts the new instance to a Servlet object and

initializes it by calling an init() method. If initialization fail the Servlet creation fail and the new instance is

garbage collected.

The Servlet initialization is done in a single threaded manner.

IBM Labs in Haifa

20

Service Phase

After the Servlet initialization, the container can ask the Servlet to serve incoming requests.

The container will call the Servlet’s service() method. A Servlet may handle many concurrent requests.

By different threads, all of them running in the same service methods. The service method should be thread safe.

Multithreading By default the servlet need to be multithread safe! One may instruct the container to make the servlet “multithread safe”

by insuring that no two thread will execute on a single servlet instance By making the Servlet class implement the SingleThreadModel interface

(deprecated)

IBM Labs in Haifa

21

Servlet Destruction A container may destroy the Servlet because:

It wants to preserve resources (this is not common). The container is shutting down.

In both cases the container will call the Servlet’s destroy() method.

Note that this means that a certain Servlet will usually stay “alive” for a very long time and is going to serve many users.

After the destruction the Servlet is garbage collected.

IBM Labs in Haifa

22

How Many Servlet Instances?

Usually, the number of servlet instances should be 1! “In the default case of a servlet not implementing

SingleThreadModel and not hosted in a distributed environment, the servlet container must use only one instance of a servlet class per servlet definition.”

“In the case of a servlet that implements the SingleThreadModel interface, the servlet container may instantiate multiple instances of that servlet so that it can handle a heavy request load while still serializing requests to a single instance.”

Taken from the Servlet API 2.3 specification.

IBM Labs in Haifa

The Programmer Contract

IBM Labs in Haifa

24

The Servlet APIs

Defines the APIs to the services that the Servlet Container provides to the Servlet Request/Response interfaces Session State services Environment services (configuration, application), etc.

Defines the Servlet life-cycle and service semantics from the Servlet Container point of view Initialization/Destruction/Service Threading models

IBM Labs in Haifa

25

The Servlet APIs Packages

Two packages: javax.servlet - General Servlet related definitions javax.servlet.http - HTTP related extension for the "general"

Servlets

Since we only deal with Web (HTTP) related Servlets we will cover and mix both of them.

IBM Labs in Haifa

26

The Servlet Interface

Defines the Servlet life-cycle APIs init(ServletConfig cfg)

Initializes the Servlet. service(ServletRequest req, ServletResponse res)

Carries out a single request from the client. destroy()

Cleans up whatever resources are being held (e.g., memory, file handles, threads) and makes sure that any persistent state is synchronized with the Servlet's current in-memory state.

Defines also two misc’ methods (getServletConfig(), getServletInfo()) Implemented by base classes

IBM Labs in Haifa

27

GenericServlet, HttpServlet

GenericServlet is an abstract (service is not provided) implementation of the Servlet interface and, for convenience, the ServletConfig interface. Servlet developers typically subclass GenericServlet, or its descendent HttpServlet (see shortly). Implements all Servlet interface methods but service

HttpServlet extends GenericServlet and adds HTTP specific functionality. HttpServlet adds the following methods:

service(HttpServletRequest, HttpServletResponse) This is an HTTP-specific version of the Servlet.service method, which

accepts HTTP specific parameters. doXXX(HttpServletRequest, HttpServletResponse)

Performs the HTTP XXX operation (where operation can be DELETE/GET/POST/PUT/TRACE); the default implementation reports an HTTP BAD_REQUEST error.

IBM Labs in Haifa

28

ServletConfig

The Servlet developer uses the ServletConfig object to get Servlet related information. getInitParameter(String name)

Returns a string containing the value of the named initialization parameter, or null if the parameter does not exist.

getInitParameterNames() Returns the names of the Servlet's initialization parameters as

an enumeration of strings. getServletContext()

Returns the context for the Servlet. getServletName()

Returns the Servlet name.

IBM Labs in Haifa

29

ServletContext

The Servlet developer uses the ServletContext object to get server related (application) information and services. getMimeType(String file)

Returns the mime type of the specified file. getRealPath(String path)

Applies alias rules to the specified virtual path and returns the corresponding real path.

log(String msg, Throwable t)/ log(String msg) Write the stacktrace and the given message string to the Servlet log file.

IBM Labs in Haifa

30

ServletRequest, HttpServletRequest

Reading stream data sent in the request: getContentLength()

Returns the size of the request entity data, or -1 if not known. getContentType()

Returns the MIME Type of the request entity data, or null if not known. getInputStream()

Returns an input stream for reading binary data in the request body. getReader()

Returns a buffered reader for reading text in the request body.

IBM Labs in Haifa

31

ServletRequest, HttpServletRequest

Methods to obtain user sent form parameters: getParameter(String name)

Returns a string containing the lone value of the specified parameter, or null if the parameter does not exist.

getParameterNames() Returns the parameter names for this request as an enumeration of

strings, or an empty enumeration if there are no parameters or the input stream is empty.

getParameterValues(String name) Returns the values of the specified parameter for the request as an array

of strings, or null if the named parameter does not exist.

IBM Labs in Haifa

32

ServletRequest, HttpServletRequest

Methods to obtain user and server addresses: getRemoteAddr()

Returns the IP address of the agent that sent the request. getRemoteHost()

Returns the fully qualified host name of the agent that sent the request. getServerName()

Returns the host name of the server that received the request. getServerPort()

Returns the port number on which this request was received.

IBM Labs in Haifa

33

ServletRequest, HttpServletRequest

Methods to get headers information: getHeaderNames(), getHeader(String)

Gets the value of the specified requested header.

Methods to get HTTP request information: getRequestURI()

Gets, from the first line of the HTTP request, the part of this request's URI that is to the left of any query string.

getQueryString() Gets any query string that is part of the HTTP request URI.

getMethod() Gets the HTTP method (for example, GET, POST, PUT) with which this

request was made.

IBM Labs in Haifa

34

ServletResponse, HttpServletResponse

Sending the response: setContentLength(int length), setContentType(String type)

Sets the content length and type for this response. getOutputStream()

Returns an output stream for writing binary response data. getWriter()

Returns a print writer for writing formatted text responses. addXXXHeader/setXXXHeader()

Adds or set a named HTTP header. The header value can be a string, int or date. For example addIntHeader() or setHeader().

setStatus(int status) Sets the status code for this response.

IBM Labs in Haifa

35

ServletResponse, HttpServletResponse

To manipulate the response buffer: setBufferSize(int size)/getBufferSize()

Set and get the size of the response buffer. flushBuffer()

Forces any content in the buffer to be written to the client. isCommitted()

Return true if data was written to the user. reset()

Reset the content of the response buffer.

IBM Labs in Haifa

Form processing

IBM Labs in Haifa

37

Submitting a Form

Form parameters constructs a list of named values

Form parameters can be obtained using the HttpServletRequest methods: getParameterNames()

Returns the parameter names for this request as an enumeration of strings.

getParameter(String name) Returns a string containing the lone value of the specified parameter, or

null if the parameter does not exist. getParameterMap()

Returns a java.util.Map with the parameters for this request

IBM Labs in Haifa

38

Form Processing Servlet

Executed by submitting a Form Prints all the submitted Form parameters as a response

IBM Labs in Haifa

39

FormServlet Servlet – The code

package com.hrl.sample;

import java.io.*;import javax.servlet.ServletException;import javax.servlet.http.*;

public class FormServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); }

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("text/html"); final PrintWriter out = resp.getWriter(); out.println("<html><body>"); out.println("<h1>Form Parameters:</h1>"); // Continue on next slide … }}

IBM Labs in Haifa

40

FormServlet Servlet – The code

// Started on previous slide

out.println("<table>");

out.println("<tr> <th> Name </th> <th> Value </th> </tr>");

final Enumeration names = req.getParameterNames();

while(names.hasMoreElements())

{

final String name = (String)names.nextElement();

final String value = req.getParameter(name);

out.println("<tr> <td> " + name + " </td> <td> " + value + " </td> </tr>");

}

out.println("</table>");

out.println("</body></html>");

}

}

IBM Labs in Haifa

41

FormServlet – Observations

Reading the posted Form parameters is easy (as it should be)

We implement both doGet() and doPost() The two HTTP methods used for sending Forms

The value of the “submit” button is submitted as well

IBM Labs in Haifa

Session state

Keeping track

IBM Labs in Haifa

43

What is Session State

We want to save short-term state on behalf of the user: Shopping cart. Authentication information.

HTTP is stateless: How can we keep state?

Enter HTTP based user session state Cookies Session State APIs

IBM Labs in Haifa

44

Cookies

The first session state solution was cookies, a special set of HTTP headers with special semantics: The server can set a cookie in the client's browser by using the set-

cookie header. The client will then send the cookie back to the server on the

following requests using the cookie header. The value of a cookie header needs to be an alphanumeric value.

But Cookies are bad: Not enough abstraction -> hard to use.

Need to manually parse a cookie. Not secure enough, data is passing back and forth. Limited in size (~100byte). Uses are afraid of cookies

IBM Labs in Haifa

45

Session State – The Servlets Way

The Servlet container is tracking the user Several tracking tools (not only cookies) Allows the servlets to associate data with the user Allows for variable QoS for the session state

The container exposes APIs to access the session data HttpSession HttpServletRequest.getSession()

IBM Labs in Haifa

46

HttpSession

Represents a single user session. Exposes the following methods:

Object getAttribute(String name) Get a stored value from the session.

Enumeration getAttributeNames() Get the named of the stored values.

removeAttribute(String name) Remove a values from the session.

setAttribute(String name, Object value) Set a value in the session.

IBM Labs in Haifa

47

HttpSession

Exposes the following methods: setMaxInactiveInterval(int interval), int getMaxInactiveInterval()

Set and get the max inactivity interval that the session can have long getCreationTime(), getLastAccessedTime()

Get the time the session was created/last accessed. String getId()

Get the id used for this session. invalidate()

Dispose the session. boolean isNew()

Was this session created now, and did arrive to the user (yet).

IBM Labs in Haifa

48

Session State Method in HttpServletRequest

HttpSession getSession() If a session is associated with the current request, this method will

return it. HttpSession getSession(boolean create)

Return a session that is associated with the current request. If the session does not exists, create new session.

IBM Labs in Haifa

49

Session Counter Servlet

Counts the number of per-user hits on the servlet

Prints some of the session meta data

IBM Labs in Haifa

50

SessionServlet – The code

package com.hrl.sample;

import java.io.*;

import javax.servlet.ServletException;

import javax.servlet.http.*;

public class SessionServlet extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

// Get the session object

final HttpSession session = req.getSession(true);

resp.setContentType("text/html");

final PrintWriter out = resp.getWriter();

// Continue on next slide …

}

}

IBM Labs in Haifa

51

SessionServlet – The code

// Started on previous slide

out.println("<html><body>");

out.println("<h1>Session Counter:</h1>");

Integer ival = (Integer) session.getAttribute("sessiontest.counter");

if(null == ival) {

ival = new Integer(1);

} else {

ival = new Integer(ival.intValue() + 1);

}

session.setAttribute("sessiontest.counter", ival);

out.println("You have hit this page <b>" + ival + "</b> times.<p>");

out.println("<p>");

// Continue on next slide …

IBM Labs in Haifa

52

SessionServlet – The code

// Started on previous slide

out.println("<h3>Session Data:</h3>");

out.println("New Session: " + session.isNew());

out.println("<br>Session ID: " + session.getId());

out.println("<br>Creation Time: " + session.getCreationTime());

out.println("<br>Last Accessed Time: " +

session.getLastAccessedTime());

out.println("</body></html>");

}

}

IBM Labs in Haifa

53

SessionServlet – Observations

One must start the session first thing in the service phase

Initially, values may be null unless initialized using a session listener

IBM Labs in Haifa

We did not talk about…

Advanced staff

IBM Labs in Haifa

55

Lots of interesting staff (20/80 principle kicked in)

80% of the APIs Many methods in Request, Response, Context et.al. Filters Session listeners Context listeners RequestDispatcher

WAR and web.xml

IBM Labs in Haifa

End