troduction
In the early days, web servers deliver static contents that are indifferent to users' requests. Java servlets are server-side programs (running inside a web server) that handle clients' requests and return a customized or dynamic response for each request. The dynamic response could be based on user's input (e.g., search, online shopping, online transaction) with data retrieved from databases or other applications, or time-sensitive data (such as news and stock prices).
Java servlets typically run on the HTTP protocol. HTTP is an asymmetrical request-response protocol. The client sends a request message to the server, and the server returns a response message as illustrated.
Server-Side Technologies
There are many (competing) server-side technologies available: Java-based (servlet, JSP, JSF, Struts, Spring, Hibernate), ASP, PHP, CGI Script, and many others.
Java servlet is the foundation of the Java server-side technology, JSP (JavaServer Pages), JSF (JavaServer Faces), Struts, Spring, Hibernate, and others, are extensions of the servlet technology.
Pre-requisites
HTML, Java Programming Language, HTTP and Apache Tomcat Server, SQL and MySQL Database System, and many others.
Apache Tomcat Server
Servlets are server-side programs run inside a Java-capable HTTP server. Apache Tomcat Server (@ http://tomcat.apache.org) is the official Reference Implementation (RI) for Java servlet and JSP, provided free by open-source foundation Apache (@ http://www.apache.org).
You need to install Tomcat to try out Java servlets. Read "How to Install Tomcat and Get Started", if necessary.
I shall denote Tomcat's installed directory as
$CATALINA_HOME
, and assume that Tomcat server is running in port 8080.Tomcat provides many servlet examples in "
$CATALINA_HOME\webapps\examples\servlets
". You can run these examples by launching Tomcat, issue URL http://localhost:8080
from a browser, and select "servlet examples" from the Tomcat's home page.Java Servlet Versions
Java Servlet has these versions: [TODO features and what is new]
- Java EE 1.2 (1999) (Java Servlet 2.2, JSP 1.1, EJB 1.1, JDBC 2.0)
- Java EE 1.3 (2001) (Java Servlet 2.3, JSP 1.2, EJB 2.0, JDBC 2.1)
- Java EE 1.4 (2003) (Java Servlet 2.4, JSP 2.0, EJB 2.1, JDBC 3.0)
- Java EE 5 (2006) (Java Servlet 2.5, JSP 2.1, JSTL 1.2, JSF 1.2, EJB 3.0, JDBC 3.0)
- Java EE 6 (2009) (Java Servlet 3.0, JSP 2.2/EL 2.2, JSTL 1.2, JSF 2.0, EJB 3.1, JDBC 4.0)
The Java Servlets Home Page is @ http://java.sun.com/products/servlet. For developers, check out the Servlet Developers @ http://java.net/projects/servlet/.
Java Servlet is the foundation technology for Java server-side programming. You need to understand Servlet thoroughly before you could proceed to other Java server-side technologies such as JavaServer Pages (JSP) and JavaServer Faces (JSF).
Review of HTTP
A HTTP Servlet runs under the HTTP protocol. It is important to understanding the HTTP protocol in order to understand server-side programs (servlet, JSP, ASP, PHP, etc) running over the HTTP. Read "HTTP Basics", if needed.
In brief, HTTP is a request-response protocol. The client sends a request message to the server. The server, in turn, returns a response message. The messages consists of two parts: header (information about the message) and body (contents). Header provides information about the messages. The data in header is organized in name-value pairs.
Read "HTTP Request and Response Messages" for the format, syntax of request and response messages, and examples.
[TODO] more
First Servlet - Hello-World
Let us begin by writing a servlet that says hello in response to a client's request. We shall use JDK and Tomcat to understand the basics, instead of IDE such as Eclipse or NetBeans. Once you understand the basics, you should use Eclipse or NetBeans to develop your production applications. JDK and Tomcat is far too primitive and not productive.
Create a new Web Application "helloservlet
"
First of all, we need to define a new web application called "
helloservlet
" in Tomcat. A web application, known as a web context in Tomcat, is a set of resources (such as HTML files, images, programs, libraries) that accomplishes that application running over the web.A Java web application has a standardized directory structure for storing various types of resources.
Create a directory "
helloservlet
" under Tomcat's "webapps
" directory (i.e., "$CATALINA_HOME\webapps\helloservlet
" where $CATALINA_HOME
denotes Tomcat's installed directory)
. Create sub-directories "WEB-INF
" and "META-INF
" under "helloservlet
". Create sub-sub-directories "classes
", "lib
" and "src
" under "WEB-INF
". Take note that the directory names are case-sensitive.The resources must be kept in the respective directories:
- "
$CATALINA_HOME
\webapps\
helloservlet
": This directory is known as context root for the web context "helloservlet
". It contains the resources that are visible by the clients, such as HTML, CSS, Scripts and images. These resources will be delivered to the clients as it is. You could create sub-directories such asimages
,css
andscripts
, to further categories the resources accessible by clients. - "
$CATALINA_HOME
\webapps\
helloservlet\WEB-INF
": This is a hidden directory that is used by the server. It is NOT accessible by the clients directly (for security reason). This is where you keep your application-specific configuration files such as "web.xml
" (which we will elaborate later). It's sub-directories contain program classes, source files, and libraries. - "
$CATALINA_HOME
\webapps\
helloservlet\WEB-INF\src
": Keep the Java program source files. It is optional but a good practice to separate the source files and classes to facilitate deployment. - "
$CATALINA_HOME
\webapps\
helloservlet\WEB-INF\classes
": Keep the Java classes (compiled from the source codes). Classes defined in packages must be kept according to the package directory structure. - "
$CATALINA_HOME
\webapps\
helloservlet\WEB-INF\lib
": keep the libraries (JAR-files), which are provided by other packages, available to this webapp only. - "
$CATALINA_HOME
\webapps\
helloservlet\META-INF
": This is also a hidden directory, to keep resources and configurations (e.g., "context.xml
") related to the server. In contrast, "WEB-INF
" is for resources related to this web application, independent of the server.
Write a Hello-World Servlet "HelloServlet.java
"
Servlets are Java programs that runs inside an HTTP server. A user can invoke a servlet by issuing a suitable URL from the browser (client). In this example, we shall write a servlet called "
HelloServlet
". A client can invoke "HelloServlet
" by issuing URL http://hostname:port/helloServlet/sayhello
.A servlet shall be kept inside a Java package (instead of the default no-name package) for proper deployment. Let's call our package "
mypkg
". Create a sub-directory called "mypkg
" under "WEB-INF\src
". Use a programming text editor to enter the following source codes, and save as "HelloServlet.java
" in "$CATALINA_HOME
\webapps\
helloservlet\WEB-INF\src\mypkg
".1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | // Save as "$CATALINA_HOME\webapps\helloservlet\WEB-INF\src\mypkg\HelloServlet.java" package mypkg; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Set the response message's MIME type response.setContentType("text/html;charset=UTF-8"); // Allocate a output writer to write the response message into the network socket PrintWriter out = response.getWriter(); // Write the response message, in an HTML page try { out.println("<!DOCTYPE html>"); out.println("<html><head>"); out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"); out.println("<title>Hello, World</title></head>"); out.println("<body>"); out.println("<h1>Hello, world!</h1>"); // says Hello // Echo client's request information out.println("<p>Request URI: " + request.getRequestURI() + "</p>"); out.println("<p>Protocol: " + request.getProtocol() + "</p>"); out.println("<p>PathInfo: " + request.getPathInfo() + "</p>"); out.println("<p>Remote Address: " + request.getRemoteAddr() + "</p>"); // Generate a random number upon each request out.println("<p>A Random Number: <strong>" + Math.random() + "</strong></p>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); // Always close the output writer } } } |
Dissecting the Program:
- We define a Java class called
HelloServlet
(in Line 8). Line 1 places this class in a package calledmypkg
(Line 2). Hence, we save the source file under "mypkg
" of the "helloservlet\WEB-INF\src
" directory, following the Java's standard package directory structure. - We need the Servlet API library to compile this program. Servlet API is not part of JDK (but belongs to Java EE). Tomcat provides a copy of servlet API called
"servlet-api.jar
" in "$CATALINA_HOME\lib
". You could copy"servlet-api.jar"
from "$CATALINA_HOME\lib
" to "$JAVA_HOME\jre\lib\ext
" (the JDK default library extension directory), or include the Servlet JAR file in yourCLASSPATH
.
To compile the program under JDK, we need to use the-d
option to specify the output destination directory to place the compiled class in "helloservlet\WEB-INF\class\mypkg
" directory.-- Change directory to $CATALINA_HOME\webapps\helloservlet\WEB-INF\classes d:\...> cd \$CATALINA_HOME\webapps\helloservlet\WEB-INF\classes -- Compile the source file into the specified destination directory d:\$CATALINA_HOME\webapps\helloservlet\WEB-INF\classes> javac -d . ..\src\mypkg\HelloServlet.java
In the above command, ".
" denotes the current directory and "..
" denotes the parent directory. The option "-d .
" specifies the destination as the current directory (i.e., "classes
"), and "..\src\mypkg\HelloServlet.java
" provides the relative path to the source file. The output is$CATALINA_HOME\webapps\helloservlet\WEB-INF\classes\mypkg\HelloServlet.class
. The compiler creates the package directory "mypkg
" automatically. - We don't write a servlet from scratch. Instead, we create a servlet by sub-classing
javax.servlet.http.HttpServlet
(in Line 8) (similar to an applet extends fromjavax.swing.JApplet
orjava.applet.Applet
, a GUI program extends fromjavax.swing.JFrame
orjava.awt.Frame
). - As mentioned, a servlet is invoked in response to a request URL issued by a client. Specifically, a client issues an HTTP request, the server routes the request message to the servlet for processing. The servlet returns a response message to the client.
- An HTTP request could use either GET or POST request methods, which will be processed by the servlet's
doGet()
ordoPost()
method, respectively. - In the
HelloServlet
, we override thedoGet()
method (as denoted by the annotation@Override
). ThedoGet()
runs in response to an HTTP GET request issued by a user via an URL.doGet()
takes two arguments, anHttpServletRequest
object and anHttpServletResponse
object, corresponding to the request and response messages. - The
HttpServletRequest
object can be used to retrieve incoming HTTP request headers and form data. TheHttpServletResponse
object can be used to set the HTTP response headers(e.g., content-type) and the response message body. - In Line 13, we set the "MIME" type of the response message to "
text/html
". The client need to know the message type in order to correctly display the data received. (Other MIME types includetext/plain
,image/jpeg
,video/mpeg
,application/xml
, and many others.) In Line 15, we retrieve aWriter
object calledout
for writing the response message to the client over the network. We then use theout.println()
to print out a proper HTML page containing the message "Hello, world!". This servlet also echoes some of the clients's request information, and prints a random number for each request.
Create the Configuration File "web.xml
"
A web user invokes a servlet, which is kept in the web server, by issuing a request URL from the browser. In this example, we shall configure the following request URL to trigger the "
HelloServlet
":http://hostname:port/helloservlet/sayhello
Create a configuration file called "
web.xml
", and save it under "helloservlet\WEB-INF
", as follows:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- To save as $CATALINA_HOME\webapps\helloservlet\WEB-INF\web.xml --> <servlet> <servlet-name>HelloWorldServlet</servlet-name> <servlet-class>mypkg.HelloServlet</servlet-class> </servlet> <!-- Note: All <servlet> elements MUST be grouped together and placed IN FRONT of the <servlet-mapping> elements --> <servlet-mapping> <servlet-name>HelloWorldServlet</servlet-name> <url-pattern>/sayhello</url-pattern> </servlet-mapping> </web-app> |
- The "
web.xml
" is called web application deployment descriptor. It provides the configuration options for that particular web application. It also defines the the mapping between URL and servlet class. - Line 1 declares that this is an XML file. The above configuration defined a servlet named "
HelloWroldServlet
", implemented in "mypkg.HelloServlet.class
" (written earlier). Clients can invoke this servlet via URL "/sayhello
", where "/
" denotes the context root of this webapp "helloservlet
". In other words, the complete URL for this servlet ishttp://hostname:port/helloservlet/sayhello
. - Take note that each servlet requires a pair of
<servlet>
and<servlet-mapping>
elements to do the mapping. Furthermore, all the<servlet>
elements must be grouped together and placed before the<servlet-mapping>
elements (as specified in the XML schema).
Running the Servlet
To run the servlet, first start the Tomcat server. Check if web context "
helloservlet
" has been deployed by observing the following messages in the Tomcat's console:May 6, 2010 10:59:44 AM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deploying web application directory helloservlet ......
Start a web browser (Firefox, IE or Chrome), and issue the following URL (as configured in the "
web.xml
"). Assume that Tomcat is running in port number 8080.http://localhost:8080/helloservlet/sayhello
We shall see the output "Hello, world!".
Try selecting "View Source" in your browser, which produces these output:
<!DOCTYPE html> <html><head> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'> <title>Hello, World</title></head> <body> <h1>Hello, world!</h1> <p>Request URI: /helloservlet/sayhello</p> <p>Protocol: HTTP/1.1</p> <p>PathInfo: null</p> <p>Remote Address: 127.0.0.1</p> <p>A Random Number: <strong>0.4320795689818858</strong></p> </body> </html>
It is important to take note that users receive the output of the servlet. User does not receive the servlet's program codes, which are kept under a hidden directory "
WEB-INF
" and not directly accessible by web users.(Everything that can possibly go wrong will go wrong...) Read "Common Error Messages". The likely errors are "404 File Not Found" and "500 Internal Server Error".
Processing HTML Form Data
Write an HTML Form
The HTML provides a
<form>...</form>
tag, which can be used to build a user input form containing elements such as text fields, password field, radio buttons, pull-down menu, checkboxes, text area, hidden field, submit and reset buttons. This allows web users to interact with the web server by submit data. For example,Use a programming text editor to create the following HTML script, and save as "
form_input.html
" under the context root "helloservlet
".1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <!DOCTYPE html> <html> <head> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'> <title>User Input Form</title> </head> <body> <h2>User Input Form</h2> <form method="get" action="echo"> <fieldset> <legend>Personal Particular</legend> Name: <input type="text" name="username" /><br /><br /> Password: <input type="password" name="password" /><br /><br /> Gender: <input type="radio" name="gender" value="m" checked />Male <input type="radio" name="gender" value="f" />Female<br /><br /> Age: <select name = "age"> <option value="1">< 1 year old</option> <option value="99">1 to 99 years old</option> <option value="100">> 99 years old</option> </select> </fieldset> <fieldset> <legend>Languages</legend> <input type="checkbox" name="language" value="java" checked />Java <input type="checkbox" name="language" value="c" />C/C++ <input type="checkbox" name="language" value="cs" />C# </fieldset> <fieldset> <legend>Instruction</legend> <textarea rows="5" cols="30" name="instruction">Enter your instruction here...</textarea> </fieldset> <input type="hidden" name="secret" value="888" /> <input type="submit" value="SEND" /> <input type="reset" value="CLEAR" /> </form> </body> </html> |
Start the tomcat server. Issue the following URL to request for the HTML page:
http://localhost:8080/helloservlet/form_input.html
Explanation:
- The
<fieldset>...</fieldset>
tag groups related elements and displays them in a box. The<legend>...</legend>
tag provides the legend for the box. - This HTML form (enclosed within
<form>...</form>
) contains the following types of input elements:- Text field (
<input type="text">
): for web users to enter text. - Radio buttons (
<input type="radio">
): choose any one (and possibly none). - Pull-down menu (
<select>
and<option>
): pull-down menu of options. - Checkboxes (
<input type="checkbox">
): chose none or more. - Text area (
<textarea>...<textarea>
): for web users to enter multi-line text. (Text field for single line only.) - Hidden field (
<input type="hidden">
): for submitting hiddenname=value
pair. - Submit button (
<input type=submit>
): user clicks this button to submit the form data to the server. - Reset button (
<input type="reset">
): resets all the input field to their default value.
name
", and an optional attribute "value
". If an element is selected, its "name=value
" pair will be submitted to the server for processing. - Text field (
- The <form> start-tag also specifies the URL for submission in the
action="url
" attribute, and the request method in themethod="get|post"
attribute.
For example, suppose that we enter "Alan Smith" in the text field, select "male", and click the "SEND" button, we will get a "404 page not found" error (because we have yet to write the processing script). BUT observe the destination URL:
http://localhost:8080/helloservlet/echo?username=Alan+Smith&gender=m&....
Observe that:
- The URL
http://localhost:8080/helloservlet/echo
is retrieved from the attributeaction="echo"
of the<form>
start-tag. Relative URL is used in this example. The base URL for the current page "form_input.html
" ishttp://localhost:8080/helloservlet/
. Hence, the relative URL "echo
" resolves intohttp://localhost:8080/helloservlet/echo
. - A
'?'
follows the URL, which separates the URL and the so-called query string (or query parameters, request parameters) followed. - The query string comprises the "
name=value
" pairs of the selected input elements (i.e., "username=Alan+Smith
" and "gender=m
"). The "name=value
" pairs are separated by an'&'
. Also take note that the blank (in "Alan Smith
") is replace by a'+'
. This is because special characters are not permitted in the URL and have to be encoded (known as URL-encoding). Blank is encoded as'+'
(or%20
). Other characters are encoded as%xx
, wherexx
is the ASCII code in hex. For example,'&'
as%26
,'?'
as%3F
. - Some input elements such as checkboxes may trigger multiple parameter values, e.g., "
language=java&language=c&language=cs
" if all three boxes are checked. - HTTP provides two request methods: GET and POST. For GET request, the query parameters are appended behind the URL. For POST request, the query string are sent in the request message's body. POST request is often preferred, as users will not see the strange string in the URL and it can send an unlimited amount of data. The amount of data that can be sent via the GET request is limited by the length of the URL. The request method is specified in the
<form method="get|post"...>
start-tag. In this tutorial, we use the GET request, so that you can inspect the query string.
Write a Servlet to Process Form Data - "EchoServlet.java
"
The form that we have written send its data to a server-side program having relative URL of "
echo
" (as specified in the action="url"
attribute of the <form>
start-tag). Let us write a servlet called EchoServlet
, which shall be mapped to the URL "echo
", to process the incoming form data. The servlet simply echoes the data back to the client.Similar to the "
HelloServlet
", we define the "EchoServlet
" under package "mypkg
", and save the source file as "$CATALINA_HOME\webapps\helloservlet\WEB-INF\src\mypkg\EchoServlet.java
".1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | // Save as "$CATALINA_HOME\webapps\helloservlet\WEB-INF\src\mypkg\EchoServlet.java" package mypkg; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; public class EchoServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Set the response message's MIME type response.setContentType("text/html; charset=UTF-8"); // Allocate a output writer to write the response message into the network socket PrintWriter out = response.getWriter(); // Write the response message, in an HTML page try { out.println("<!DOCTYPE html>"); out.println("<html><head>"); out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"); out.println("<title>Echo Servlet</title></head>"); out.println("<body><h2>You have enter</h2>"); // Retrieve the value of the query parameter "username" (from text field) String username = request.getParameter("username"); // Get null if the parameter is missing from query string. // Get empty string or string of white spaces if user did not fill in if (username == null || (username = htmlFilter(username.trim())).length() == 0) { out.println("<p>Name: MISSING</p>"); } else { out.println("<p>Name: " + username + "</p>"); } // Retrieve the value of the query parameter "password" (from password field) String password = request.getParameter("password"); if (password == null || (password = htmlFilter(password.trim())).length() == 0) { out.println("<p>Password: MISSING</p>"); } else { out.println("<p>Password: " + password + "</p>"); } // Retrieve the value of the query parameter "gender" (from radio button) String gender = request.getParameter("gender"); // Get null if the parameter is missing from query string. if (gender == null) { out.println("<p>Gender: MISSING</p>"); } else if (gender.equals("m")) { out.println("<p>Gender: male</p>"); } else { out.println("<p>Gender: female</p>"); } // Retrieve the value of the query parameter "age" (from pull-down menu) String age = request.getParameter("age"); if (age == null) { out.println("<p>Age: MISSING</p>"); } else if (age.equals("1")) { out.println("<p>Age: < 1 year old</p>"); } else if (age.equals("99")) { out.println("<p>Age: 1 to 99 years old</p>"); } else { out.println("<p>Age: > 99 years old</p>"); } // Retrieve the value of the query parameter "language" (from checkboxes). // Multiple entries possible. // Use getParameterValues() which returns an array of String. String[] languages = request.getParameterValues("language"); // Get null if the parameter is missing from query string. if (languages == null || languages.length == 0) { out.println("<p>Languages: NONE</p>"); } else { out.println("<p>Languages: "); for (String language : languages) { if (language.equals("c")) { out.println("C/C++ "); } else if (language.equals("cs")) { out.println("C# "); } else if (language.equals("java")) { out.println("Java "); } } out.println("</p>"); } // Retrieve the value of the query parameter "instruction" (from text area) String instruction = request.getParameter("instruction"); // Get null if the parameter is missing from query string. if (instruction == null || (instruction = htmlFilter(instruction.trim())).length() == 0 || instruction.equals("Enter your instruction here...")) { out.println("<p>Instruction: NONE</p>"); } else { out.println("<p>Instruction: " + instruction + "</p>"); } // Retrieve the value of the query parameter "secret" (from hidden field) String secret = request.getParameter("secret"); out.println("<p>Secret: " + secret + "</p>"); // Get all the names of request parameters Enumeration names = request.getParameterNames(); out.println("<p>Request Parameter Names are: "); if (names.hasMoreElements()) { out.print(htmlFilter(names.nextElement().toString())); } do { out.print(", " + htmlFilter(names.nextElement().toString())); } while (names.hasMoreElements()); out.println(".</p>"); // Hyperlink "BACK" to input page out.println("<a href='form_input.html'>BACK</a>"); out.println("</body></html>"); } finally { out.close(); // Always close the output writer } } // Redirect POST request to GET request. @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); } // Filter the string for special HTML characters to prevent // command injection attack public static String htmlFilter(String message) { if (message == null) return null; int len = message.length(); StringBuffer result = new StringBuffer(len + 20); char aChar; for (int i = 0; i < len; i++) { aChar = message.charAt(i); switch (aChar) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(aChar); } } return (result.toString()); } } |
Dissecting the Program:
- The query string comprises
name=value
pairs. We can retrieve the query parameters from the request message (captured indoGet()
's argumentHttpServletRequest request
) via one of the following methods:request.getParameter("paramName") // Returns the parameter value in a String. // Returns null if parameter name does not exist. // Returns the first parameter value for a multi-value parameter. request.getParameterValues("paramName") // Return all the parameter values in a String[]. // Return null if the parameter name does not exist. request.getParameterNames() // Return all the parameter names in a java.util.Enumeration, possibly empty.
- Take note that the parameter name is case sensitive.
- We use
request.getParameter("paramName")
to retrieve the parameter value for most of the single-value input elements (such as text field, radio button, text area, etc). If the parameter is present (notnull
), wetrim()
the returned string to remove the leading and trailing white spaces. - We also replace the special HTML characters (
>
,<
,&
,"
) with the HTML escape sequences in the input strings, before we echo them back to the client viaout.println()
. This step is necessary to prevent the so-called command-injection attack, where user enters a script into the text field. The replacement is done via astatic
helper methodhtmlFilter()
. [Rule of thumb: Any text string taken from the client and echoing back viaout.println()
needs to be filtered!] - If the parameter could posses multiple values (e.g., checkboxes), we use
request.getParameterValues()
, which returns an array ofString
ornull
if the parameter does not exist. - One of the nice features of Java servlet is that all the form data decoding (i.e., URL-decoding) is handled automatically. That is,
'+'
will be decoded to blank,%xx
decoded into the corresponding character.
Configure the Servlet URL mapping in "web.xml
"
Our
<form>
's action
attribute refers to relative URL "echo
", which has to be mapped to the EchoServlet.class
in the web application deployment descriptor file "WEB-INF\web.xml
":<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- To save as $CATALINA_HOME\webapps\helloservlet\WEB-INF\web.xml --> <servlet> <servlet-name>HelloWorldServlet</servlet-name> <servlet-class>mypkg.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>EchoServletExample</servlet-name> <servlet-class>mypkg.EchoServlet</servlet-class> </servlet> <!-- Note: All <servlet> elements MUST be grouped together and placed IN FRONT of the <servlet-mapping> elements --> <servlet-mapping> <servlet-name>HelloWorldServlet</servlet-name> <url-pattern>/sayhello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>EchoServletExample</servlet-name> <url-pattern>/echo</url-pattern> </servlet-mapping> </web-app>
Run the EchoServlet
Start the Tomcat server. Issue URL
http://localhost:8080/helloservlet/form_input.html
. Fill up the form, click the submit button to trigger the servlet. Alternatively, you could issue a URL with query string.Form-Data Submission Methods
Two request methods, GET and POST, are available for submitting form data, to be specified in the
<form>
's attribute "method=GET|POST
". GET and POST performs the same basic function. That is, gather the name-value pairs of the selected input elements, URL-encode, and pack them into a query string. However, in a GET request, the query string is appended behind the URL, separated by a '?'
. Whereas in a POST request, the query string is kept in the request body (and not shown in the URL). The length of query string in a GET request is limited by the maximum length of URL permitted, whereas it is unlimited in a POST request. I recommend POST request for production, as it does not show the strange looking query string in the URL, even if the amount of data is limited. In this tutorial, I use GET method, so that you can inspect the query string on the URL.To try out the POST request, modify the "
form_input.html
":<form method="post" action="echo"> ...... </form>
Inside the servlet, GET request is processed by the method
doGet()
, while POST request is processed by the method doPost()
. Since they often perform identical operations, we re-directdoPost()
to doGet()
(or vice versa), as follows:public class MyServlet extends HttpServlet { // doGet() handles GET request @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ...... ...... } // doPost() handles POST request @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { doGet(request, response); // call doGet() } }
Request Header and Response Header
HTTP is a request-response protocol. The client sends a request message to the server. The server, in turn, returns a response message. The request and response messages consists of two parts: header (information about the message) and body (contents). Header provides information about the messages. The data in header is organized in name-value pairs. Read "HTTP Request and Response Messages" for the format, syntax of request and response messages.
HttpServletRequest
The request message is encapsulated in an
HttpServletRequest
object, which is passed into the doGet()
methods. HttpServletRequest
provides many methods for you to retrieve the headers:- General methods:
getHeader(name)
,getHeaders(name)
,getHeaderNames()
. - Specific methods:
getContentLength()
,getContentType()
,getCookies()
,getAuthType()
, etc. - URL related:
getRequestURI()
,getQueryString()
,getProtocol()
,getMethod()
.
Example: See Request Header Example.
HttpServletResponse
The response message is encapsulated in the
HttpServletResponse
, which is passed into doGet()
by reference for receiving the servlet output.setStatusCode(int statuscode)
,sendError(int code, String message)
,sendRedirect(url)
.response.setHeader(String headerName, String headerValue)
.setContentType(String mimeType)
,setContentLength(int length)
, etc.
Example: [TODO]
Session Tracking
HTTP is a stateless protocol. In other words, the current request does not know what has been done in the previous requests. This creates a problem for applications that runs over many requests, such as online shopping (or shopping cart). You need to maintain a so-called session to pass data among the multiple requests.
You can maintain a session via one of these three approaches:
- Cookie: A cookie is a small text file that is stored in the client's machine, which will be send to the server on each request. You can put your session data inside the cookie. The biggest problem in using cookie is clients may disable the cookie.
- URL Rewriting: Passes data by appending a short text string at the end of every URL, e.g.,
http://host/path/file.html;jsessionid=123456
. You need to rewrite all the URLs (e.g., the "action
" attribute of<form>
) to include the session data. - Hidden field in an HTML form: pass data by using hidden field tag (
<input type="hidden" name="session" value="...." />
). Again, you need to include the hidden field in all the pages.
For detailed information, read "HTTP state and session management".
HttpSession
Programming your own session tracking (using the above approaches) is tedious and cumbersome. Fortunately, Java Servlet API provides a session tracking facility, via an interface called
javax.servlet.http.HttpSession
. It allows servlets to:- View and manipulate information about a session, such as the session identifier, creation time, and last accessed time.
- Bind objects to sessions, allowing user information to persist across multiple user requests.
The procedure is as follows:
- Check if a session already exists. If so, use the existing session object; otherwise, create a new session object. Servlet API automates this step via the
getSession()
method ofHttpServletRequest
:// Retrieve the current session. Create one if not exists HttpSession session = request.getSession(true); HttpSession session = request.getSession(); // same as above // Retrieve the current session. // Do not create new session if not exists but return null HttpSession session = request.getSession(false);
The first statement returns the existing session if exists, and create a newHttpSession
object otherwise. Each session is identified via a session ID. You can usesession.getID()
to retrieve the session ID string.HttpSession
, by default, uses cookie to pass the session ID in all the client's requests within a session. If cookie is disabled,HttpSession
switches to URL-rewriting to append the session ID behind the URL. To ensure robust session tracking, all the URLs emitted from the server-side programs should pass thru the methodresponse.encodeURL(url)
. If cookie is used for session tracking,encodeURL(url)
returns theurl
unchanged. If URL-rewriting is used,encodeURL(url)
encodes the specifiedurl
by including the session ID. - The session object maintains data in the form of
key-value
pairs. You can usesession.getAttribute(key)
to retrieve thevalue
of an existing key,session.setAttribute(key,value)
to store newkey-value
pair, andsession.removeAttribute(key)
to remove an existingkey-value
pair. For example,// Allocate a shopping cart (assume to be a list of String) List<String> shoppingCart = new ArrayList<>(); // Populate the shopping cart shoppingCart.add("Item 1"); ..... // Retrieve the current session, create one if not exists HttpSession session = request.getSession(true); // Place the shopping cart inside the session synchronized (session) { // synchronized to prevent concurrent updates session.setAttribute("cart", shoppingCart); } .....
Any page within the session can retrieve the shopping cart:// Retrieve the current session, do not create new session HttpSession session = request.getSession(false); if (session != null) { List<String> theCart = (List<String>)session.getAttribute("cart"); if (theCart != null) { // cart exists? for (String item : theCart) { ...... } } }
- You can use
session.invalidate()
to terminate and remove a session. You can use setsetMaxInactiveInterval()
andgetMaxInactiveInterval()
to set and get the inactive interval from the last client request, before the server invalidate the session.
Example
The following servlet demonstrates the use of session, by counting the number of accesses within this session from a particular client. We also use
getID()
to retrieve the session ID,getCreationTime()
and getLastAccessedTime()
to get the session creation and last accessed times.SessionServlet.java
// Save as "$CATALINA_HOME\webapps\helloservlet\WEB-INF\src\mypkg\SessionServlet.java" package mypkg; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Date; public class SessionServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Set the response message's MIME type response.setContentType("text/html;charset=UTF-8"); // Allocate a output writer to write the response message into the network socket PrintWriter out = response.getWriter(); // Return the existing session if there is one. Create a new session otherwise. HttpSession session = request.getSession(); Integer accessCount; synchronized(session) { accessCount = (Integer)session.getAttribute("accessCount"); if (accessCount == null) { accessCount = 0; // autobox int to Integer } else { accessCount = new Integer(accessCount + 1); } session.setAttribute("accessCount", accessCount); } // Write the response message, in an HTML page try { out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> out.println("<title>Session Test Servlet</title></head><body>"); out.println("<h2>You have access this site " + accessCount + " times in this session.</h2>"); out.println("<p>(Session ID is " + session.getId() + ")</p>"); out.println("<p>(Session creation time is " + new Date(session.getCreationTime()) + ")</p>"); out.println("<p>(Session last access time is " + new Date(session.getLastAccessedTime()) + ")</p>"); out.println("<p>(Session max inactive interval is " + session.getMaxInactiveInterval() + " seconds)</p>"); out.println("<p><a href='" + request.getRequestURI() + "'>Refresh</a>"); out.println("<p><a href='" + response.encodeURL(request.getRequestURI()) + "'>Refresh with URL rewriting</a>"); out.println("</body></html>"); } finally { out.close(); // Always close the output writer } } }
web.xml
...... <servlet> <servlet-name>SessionTestServlet</servlet-name> <servlet-class>mypkg.SessionServlet</servlet-class> </servlet> ...... ...... <servlet-mapping> <servlet-name>SessionTestServlet</servlet-name> <url-pattern>/sessiontest</url-pattern> </servlet-mapping>
Running the Servlet
You can use URL
http://localhost:8080/helloservlet/sessiontest
to access this servlet. Try refreshing the page. Try also closing and restart the browser, and issue the URL.Under Firefox, a cookie named
jsessionid
is created for this session. The value of the cookie is the same as the return value of session.getID()
. By default, Servlet API uses a cookie for managing session, but will automatically switch into URL rewriting if cookie is disabled. To ensure robust session tracking, all the URLs emitted from the server-side programs should pass thru the method response.encodeURL(url)
. If cookie is used for session tracking, encodeURL(url)
returns the url
unchanged. If URL-rewriting is used, encodeURL(url)
encodes the specified url
by including the session ID. The session data are kept in the server, only a session ID is passed to the client.Try disabling the cookie, and use (a) the refresh button (F5), (b) refresh and clear cache (Ctrl-F5), (c) the refresh link, and (d) the refresh with URL re-writing, to refresh the page.
ServletConfig and ServletContext
ServletConfig
ServletConfig
is a servlet configuration object used by a servlet container (e.g., Tomcat, GlassFish) to pass information to a servlet during initialisation. It is passed as the argument in theinit()
method. The init parameters are declared in the application-specific deployment descriptor "web.xml
". You can retrieve the init parameters viaServletConfig.getInitParam("paramName")
method. For example, suppose the application's "web.xml
" declares these initialisation parameters about database connection:<web-app ...> ... <servlet> ... <init-param> <param-name>databaseURL</param-name> <param-value>jdbc:mysql://localhost:3306/ebookshop</param-value> </init-param> <init-param> <param-name>user</param-name> <param-value>myuser</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>xxxx</param-value> </init-param> </servlet> ... </web-app>
You can retrieve the init parameters in the servlet's
init()
method, as follow:@Override public void init(ServletConfig config) throws ServletException { super.init(config); // Read the init params and save them in web context for use by // servlets and JSP within this web app. ServletContext context = config.getServletContext(); context.setAttribute("databaseURL", config.getInitParameter("databaseURL")); context.setAttribute("user", config.getInitParameter("user")); context.setAttribute("password", config.getInitParameter("password")); ...... }
ServletContext
There is one
ServletContext
per "web application". [A better name for ServletContext
is ApplicationContext
or WebappContext
.] It can be retrieved viaServletConfig.getServletContext()
. A servlet can use it to communicate with its servlet container (Tomcat, Glassfish), for example, to get the MIME type of a file, dispatch requests, or write to a log file. ServletContext
has an "application" scope, and can also be used to pass information between servlets and JSPs within the same application, via methodssetAttribute("name", object)
and getAttribute("name")
.Example [TODO]
Developing and Deploying Web Applications using IDE
It is a lot more productive and efficient to use an IDE to develop your web application. You could start/stop your servers from IDE directly. You could debug your web application in IDE, like debugging standalone application. You could ....
Developing and Deploying Web Applications in NetBeans
Developing and Deploying Web Applications in Eclipse
Tomcat's Servlet Examples
Tomcat provides a number of excellent servlet examples in "
$CATALINA_HOME\webapps\examples
". The servlet source files are kept under "$CATALINA_HOME\webapps\examples\WEB-INF\classes
", together with the compiled classes. To run the examples, start Tomcat server. Issue URL http://localhost:8080
from a browser, and select "servlet examples" from the home page.Let's study these examples. I made some modifications to fit my styles. Read "Java Servlet Examples".
Database Servlet
Read "Java Servlet Case Study" and "Java Servlet Case Study Continue".
Servlet API – A Deeper Look
A servlet is a Java web component, managed by a servlet container (such as Apache Tomcat or Glassfish), which generates dynamic content in response to client's request. A servlet container (or servlet engine) is a web server extension which provides servlet functionality. A servlet container contains and manages servlets throughout their lifecycle.
Interface Servlet
The
Servlet
interface is the central abstraction of the Java servlet API. HttpServlet
- the most commonly servlet which handles HTTP requests, is a subclass of GenericServlet
which implements Servlet
interface.The
Servlet
interface declares these abstract
methods:// Servlet's lifecycle void init(ServletConfig config) void destroy() void service(ServletRequest request, ServletResponse response) // Servlet configuration and information ServletConfig getServletConfig() String getServletInfo()
A Servlet's Life cycle
A servlet's life cycle is managed via the
init()
, service()
and destroy()
methods.Loading and Initialization
Servlet container (e.g., Tomcat or Glassfish) is responsible for loading and instantiating servlets. It may load and instantiate servlets when it is started, or delay until it determines that the servlet is needed to service a request (usually at the first request to the servlet).
The servlet container invokes the
init(ServletConfig)
method of the servlet, providing a ServletConfig
object as an argument. init()
runs only once. It is usually used to read persistent configuration data and initialize costly resource.This
ServletConfig
object allows the servlet to access initialization parameters for this particular servlet. These parameters are defined in the web application deployment descriptor file (i.e., “web.xml
”), under the servlet's name, as follows:<servlet> <servlet-name>ServletName</servlet-name> <servlet-class>ServletClassFile</servlet-class> <init-param> <param-name>initParam1</param-name> <param-value>initParam1Value</param-value> </init-param> <init-param> <param-name>initParam2</param-name> <param-value>initParam2Value</param-value> </init-param> </servlet>
The
ServletConfig
interface defines these methods to retrieve the initialization parameters for this servlet.String getInitParameter(String name) java.util.Enumeration getInitParameterNames()
For example,
public void init(ServletConfig config) throws ServletException {
// Read all the init parameters for this servlet
Enumeration e = config.getInitParameterNames();
while (e.hasMoreElements()) {
String initParamName = (String)e.nextElement();
String initParamValue = config.getInitParameter(initParamName);
......
}
}
The
ServletConfig
interface is implemented by HTTPServlet
and GenericServlet
. Hence, the getInitParameter()
and getInitParameterNames()
method can be called directly within init()
or service()
.The
ServletConfig
also gives servlet access to a ServletContext
object that provides information about this web context (aka web application). ServletContext
will be discussed later.In Service
Once a servlet is initialized, the servlet container invokes its
service()
method to handle client requests. This method is called once for each request. Generally, the servlet container handle concurrent request to the same servlet by running service()
on different threads (unless SingleThreadModel
interface is declared).For
HttpServlet
, service()
dispatches doGet()
, doPost()
, doHead()
, doOptions()
, doTrace()
, etc, to handle HTTP GET, POST, HEAD, OPTIONS, TRACE, etc, request respectively.The
service()
method of an HttpServlet
takes two arguments, an HttpServletRequest
object and an HttpServletResponse
object that corresponds to the HTTP request and response messages respectively.End of Service
When the servlet container decides that a servlet should be removed from the container (e.g., shutting down the container or time-out, which is implementation-dependent), it calls the
destroy()
method to release any resource it is using and save any persistent state. Before the servlet container calls the destroy()
, it must allow all service()
threads to complete or time-out.Interface ServletContext
The
ServletContext
interface defines a servlet's view of the web application in which it is running (a better name is actually ApplicationContext
). Via the ServletContext
object, a servlet can communicate with the container, e.g., write to event log, get the URL reference to resources, and get and set attributes that other servlets in the same context can access.There is one
ServletContext
object for each web application deployed into a container. You can specify initialization parameters for a web context (that are available to all the servlet under the web context) in the web application deployment descriptor, e.g.,<web-app ......> <context-param> <param-name>jdbcDriver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>databaseUrl</param-name> <param-value>jdbc:mysql://localhost/eshop</param-value> </context-param> ...... </web-app>
Servlets under this web context can access the context's initialization parameters via the
ServletConfig
's methods:// ServletConfig
String getInitParameter(String name)
java.util.Enumeration getInitParameterNames()
A servlet can bind an attribute of name-value pair into the
ServletContext
, which will then be available to other servlet in the same web application. The methods available are:// ServletContext
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
java.util.Enumeration getAttributeNames()
Other methods in
ServletContext
are:// Write message to event log void log(String message) // Get container info String getServerInfo() int getMajorVersion() int getMinorVersion()
The
ServletContext
provides direct access to static content of the web application (such as HTML, GIF files), via the following methods:java.net.URL getResource(String path) java.io.InputStream getResourceAsStream(String path)
Dispatch Request
When building a web application, it is often useful to forward a request to another servlet, or to include the output of another servlet in the response. The
RequestDispatcher
interface supports these. The RequestDispatcher
can be obtained via ServletContext
:// ServletContext
RequestDispatcher getRequestDispatcher(String servletPath)
RequestDispatcher getNamedDispatcher(String servletName)
Once the servlet obtained a
RequestDispatcher
of another servlet within the same web application, it could include or forward the request to that servlet, e.g.,RequestDispatcher rd = context.getRequestDispatcher("/test.jsp?isbn=123");
rd.include(request, response);
// or
rd.forward(request, response);
Filtering
A filter is a reusable piece of code that can transform the content of HTTP requests, responses, and header information. Examples of filtering components are:
- Authentication filters
- Logging and auditing filters
- Image conversion filters
- Data compression filters
- Encryption filters
- Tokenizing filters
- Filters that trigger resource access events
- XSL/T filters that transform XML content
- MIME-type chain filters
- Caching filters
[TODO] more
Web Application Deployment Descriptor "web.xml
"
The "
web.xml
" contains the web application deployment descriptors. Tomcat's has a system-wide (global) "web.xml
" in "$CATALINA_HOME\conf
". Each web application has its own "web.xml
" in "ContextRoot
\WEB-INF
", which overrides the global settings. Tomcat monitors web.xml
for all web applications and reloads the web application when web.xml
changes, if reloadable
is set to true
.A Sample "web.xml
"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!-- General Description of the web application --> <display-name>Workshop Continue</display-name> <description>We shall continue our e-bookstore...</description> <!-- Context initialization parameters --> <!-- Provide the database related parameters --> <context-param> <param-name>jdbcDriver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>databaseUrl</param-name> <param-value>jdbc:mysql://localhost/eshop</param-value> </context-param> <!-- Define servlets --> <servlet> <servlet-name>BookQuery</servlet-name> <servlet-class>BookQueryServlet</servlet-class> <init-param> <param-name>popularAuthor</param-name> <param-value>Kelvin Jones</param-value> </init-param> </servlet> <!-- Define servlet's URL mapping --> <servlet-mapping> <servlet-name>BookQuery</servlet-name> <url-pattern>/query</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <mime-mapping> <extension>pdf</extension> <mime-type>application/pdf</mime-type> </mime-mapping> <!-- For directory request --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> </welcome-file-list> <error-page> <error-code>404</error-code> <location>/404.html</location> </error-page> </web-app> |
Syntax for "web.xml
"
Servlets 3.0 "web.xml
" Syntax
Tomcat 7 and Glassfish 3.1 supports Servlet 3.0.
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true"> ...... </web-app>
Servlets 2.5 "web.xml
" Syntax
Tomcat 6 and Glassfish 3 supports Servlets 2.5, JSP 2.1 and JSF 2.0.
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> ....... </web-app>
Servlets 2.4 "web.xml
" Syntax
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> ....... </web-app>
Servlet Deployment Descriptor
To deploy a servlet, you need to write one pair of
<servlet>
and <servlet-mapping>
elements, with a matching (but arbitrary and unique) <servlet-name>
. The <servlet-class>
specifies the fully-qualified name of the servlet class. The <url-pattern>
specifies the URL. For example,<web-app ...> <servlet> <servlet-name>ServletName</servlet-name> <servlet-class>mypkg.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletName</servlet-name> <url-pattern>/MyURL</url-pattern> </servlet-mapping> </web-app>
The resultant URL is
http://hostname:port/WebContext/MyURL
.You can use wildcard '
*
' in the <url-pattern>
for pattern matching. For example, /MyURL.*
(which is matched by /MyURL.html
and etc.), /MyURL/*
(which is matched by /MyURL/test
, and etc.)Always use a custom URL for servlet, as you could choose a short and meaningful URL and include initialisation. parameters, filter, security setting in the deployment descriptor (see the next section).
Servlet Initialization Parameters
You can pass initialization parameters in the form of
name-value
pairs into a particular servlet from "web.xml
". For example,<web-app ...> <servlet> <servlet-name>ServletName</servlet-name> <servlet-class>mypkg.MyServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>listing</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletName</servlet-name> <url-pattern>/MyURL</url-pattern> </servlet-mapping> </web-app>
Inside the servlet, you can retrieve the init parameters via the
ServletConfig
object:package mypkg; public class MyServlet extends HttpServlet { private boolean debug = false, listing = false; @Override public void init() { ServletConfig config = getServletConfig(); String strDebug = config.getInitParameter("debug"); if (strDebug.equals("true")) debug = true; String strListing = config.getInitParameter("listing"); if (strListing.equals("true")) listing = true; } ...... }
Application Initialization Parameters
Specified in webapp's "
WEB-INF\web.xml
", and available to all the servlets under this webapp. You can use the getInitParameter()
method of ServletContext
object to retrieve the init parameters.<web-app ......> <context-param> <param-name>email</param-name> <param-value>query@abcde.com</param-value> </context-param> ...... </web-app>
Server-wide Initialization Parameters
Similar to application init parameters, but defined in the global "
$CATALINA_HOME\conf\web.xml
".<context-param> <param-name>email</param-name> <param-value>query@abcde.com</param-value> </context-param>
Use the
getInitParameter()
method of ServletContext
object to retrieve the init parameters.Welcome Page
Specifies the page to be displayed for request to web context root. For example,
<web-app ...> ...... <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>test/index.html</welcome-file> </welcome-file-list> </web-app>
Servlet 3.0
Servlet API 3.0 introduces these annotations to simplify deployment in
javax.servlet.annotation
package:@WebServlet
: Define a servlet component@WebInitParam
: Define initialization parameters for a servlet@WebListener
: Define a listener@WebFilter
: Define a filter@MultipartConfig
: For multipart file upload
For example,
@WebServlet( name = "HelloServletExample", urlPatterns = {"/sayhello"}, initParams = { @WebInitParam(name = "param1", value = "value1"), @WebInitParam(name = "param2", value = "value2")} ) public class HelloServlet extends HttpServlet { ...... }
The above is equivalent to the following configuration in "
web.xml
" prior to Servlet 3.0. The web application deployment descriptor "web.xml
" has become optional in Servlet 3.0. Instead, the container at run time will process the annotations of the classes in WEB-INF/classes
and JAR files in lib
directory.// web.xml
<servlet>
<servlet-name>HelloServletExample</servlet-name>
<servlet-class>hello.HelloServlet</servlet-class>
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>value2</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloServletExample</servlet-name>
<url-pattern>/sayhello</url-pattern>
</servlet-mapping>
@WebServlet
@WebServlet
defines a servlet component and its metadata, with the following attributes:String[] urlPatterns
: An array of String declaring theurl-pattern
forservlet-mapping
. Default is an empty array{}
.String[] value
:urlPatterns
.String name
:servlet-name
, default is empty string""
.loadOnStartup
: Theload-on-startup
order of the servlet, default is -1.WebInitParam[] initParams
: The init parameters of the servlet, default is an empty array{}
.boolean asyncSupported
: Declares whether the servlet supports asynchronous operation mode, default is false.String smallIcon
,String largeIcon
,String description
: icon and description of the servlet.
Example:
@WebServlet("/sayHello") public class Hello1Servlet extends HttpServlet { ...... } // One URL pattern @WebServlet(urlPatterns = {"/sayhello", "/sayhi"}) public class Hello2Servlet extends HttpServlet { ...... } // More than one URL patterns
@WebInitParam
@WebInitParam
is Used to declare init params in servlet, with the following attributes:String name
andString value
(required): Declare the name and value of the init parameter.String description
(optional) description, default empty string""
.
See the above example.
@WebFilter
@WebFilter
defines a filter (which implements javax.servlet.Filter
interface).For example, the following filter log the request time for all the requests (
urlPattern="/*"
).1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package mypkg; import java.io.*; import java.util.logging.Logger; import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.*; @WebFilter(urlPatterns={"/*"}) public class RequestTimerFilter implements Filter { private static final Logger logger = Logger.getLogger(RequestTimerFilter.class.getName()); @Override public void init(FilterConfig config) throws ServletException { logger.info("RequestTimerFilter initialized"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long before = System.currentTimeMillis(); chain.doFilter(request, response); long after = System.currentTimeMillis(); String path = ((HttpServletRequest)request).getRequestURI(); logger.info(path + ": " + (after - before) + " msec"); } @Override public void destroy() { logger.info("RequestTimerFilter destroyed"); } } |
@WebListener
@WebListener
defines a listener (which extends ServletContexListner
, ServletRequestListner
or HttpSessionListner
). For example,@WebListener() public class MyContextListner extends ServletContextListner { ...... }
@MultipartConfig
For uploading file using
multipart/form-data
POST Request. Read "Uploading Files in Servlet 3.0".
Thanks for your info i like your article which u r sharing the knowledge is excellent.Thank u so much again
ReplyDeletejava training in chennai |
java training institutes in chennai