Servlets are rarely accessed by typing their URL
directly in the browser. The most common use of servlets is to process
data entered by users in an HTML form. In this section, we illustrate
this process.
Before digging into the servlet code and HTML markup, let's take a look at the web.xml file for this new application:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<servlet>
<servlet-name>FormHandlerServlet</servlet-name>
<servlet-class>
net.ensode.glassfishbook.formhandling.FormHandlerServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FormHandlerServlet</servlet-name>
<url-pattern>/formhandlerservlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>dataentry.html</welcome-file>
</welcome-file-list>
</web-app>
This web.xml file is
very similar to the one we saw in the previous section. However, it
contains an XML tag we haven't seen before, namely the<welcome-file> tag. The<welcome-file>
tag determines which file to direct to when a user types a URL ending
in the application's context root (for this example, the URL would be http://localhost:8080/formhandling, as we are naming our WAR file formhandling.war and not specifying a custom context root). We will name the HTML file containing the form as dataentry.html. This way, GlassFish will render it in the browser when the user types our application's URL and does not specify a filename.
If no<welcome-file> is specified in the application's web.xml file, GlassFish will look for a file named index.html and use it as the welcome file. If it can't find it, it will look for a file named index.jsp and use it as the welcome file. If it can't find either one, it will display a directory listing.
The HTML file containing the form for our application looks as follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Data Entry Page</title>
</head>
<body>
<form method="post" action="formhandlerservlet">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td>Please enter some text:</td>
<td><input type="text" name="enteredValue" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"></td>
</tr>
</table>
</form>
</body>
</html>
Notice how the value for the form's action attribute matches the value of the servlet's<url-pattern> in the application's web.xml file (minus the initial slash). As the value of the form's method attribute is post, our servlet's doPost() method will be executed when the form is submitted.
Let's now take a look at our servlet's code:
package net.ensode.glassfishbook.formhandling;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FormHandlerServlet extends HttpServlet
{
protected void doPost(HttpServletRequest request, HttpServletResponse response)
{
String enteredValue;
servletHTML forms, processingenteredValue = request.getParameter("enteredValue");
response.setContentType("text/html");
PrintWriter printWriter;
try
{
printWriter = response.getWriter();
printWriter.println("<p>");
printWriter.print("You entered: ");
printWriter.print(enteredValue);
printWriter.print("</p>");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
As can be seen in this example, we obtain a reference to the value the user typed by calling the request.getParameter() method. This method takes a single String
object as its sole parameter. The value of this string must match the
name of the input field in the HTML file. In this case, the HTML file
has a text field named enteredValue:
<input type="text" name="enteredValue" />
Therefore, the servlet has a corresponding line:
enteredValue = request.getParameter("enteredValue");
This line of code is used to obtain the text entered by the user and store it in the string variable named enteredValue
(the name of the variable does not need to match the input field name,
but naming it that way is good practice to make it easy to remember what
value the variable is holding).
After packaging the previous three files in a WAR file called formhandling.war and deploying the WAR file, we can see the rendered dataentry.html file by entering http://localhost:8080/formhandling in the browser:
After the user enters some text in the text field and submits the form (either by hitting the Enter key or clicking on the Submit button), we should see the output of the servlet:
The HttpServletRequest.getParameter()
method can be used to obtain the value of any HTML input field that can
return only one value (text boxes, text areas, single selects, radio
buttons, hidden fields, and so on). The procedure to obtain any of
these fields' values is identical. In other words, the servlet doesn't
care if the user typed in the value in a text field, selected it from a
set of radio buttons, and so on. As long as the input field's name
matches the value passed to the getParameter() method, the previous code will work.
When dealing with radio buttons, all related radio buttons must have the same name. Calling the HttpServletRequest.getParameter() method and passing in the name of the radio buttons will return the value of the selected radio button.
Some HTML input fields such
as checkboxes and multiple select boxes allow the user to select more
than one value. For these fields, instead of using the HttpServletRequest.getParameter() method, the HttpServletRequest.getParameterValues()
method is used. This method also takes a string containing the input
field's name as its only parameter and returns an array of strings
containing all the values that were selected by the user.
Let's add a second
HTML file and a second servlet to our application to illustrate this
case. The relevant sections of this HTML tag are shown in the following
code:
<form method="post" action="multiplevaluefieldhandlerservlet">
<p>Please enter one or more options.</p>
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td><input name="options" type="checkbox" value="option1" />
Option 1
</td>
</tr>
<tr>
<td><input name="options" type="checkbox" value="option2" />
Option 2
</td>
</tr>
<tr>
<td><input name="options" type="checkbox" value="option3" />
Option 3
</td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
<td></td>
</tr>
</table>
</form>
The new HTML file contains a
simple form having three checkboxes and a submit button. Notice how
every checkbox has the same value for its name attribute. As we mentioned before, any checkboxes that are clicked by the user will be sent to the servlet.
Let's now take a look at the servlet that will handle this HTML form:
package net.ensode.glassfishbook.formhandling;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MultipleValueFieldHandlerServlet extends HttpServlet
{
protected void doPost(HttpServletRequest request, HttpServletResponse response)
{
String[] selectedOptions = request.getParameterValues("options");
response.setContentType("text/html");
try
{
PrintWriter printWriter = response.getWriter();
printWriter.println("<p>");
printWriter.print("The following options were selected:");
printWriter.println("<br/>");
if (selectedOptions != null)
{
for (String option : selectedOptions)
{
printWriter.print(option);
printWriter.println("<br/>");
}
}
else
{
printWriter.println("None");
}
printWriter.println("</p>");
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
This code calls the request.getParameterValues() method and assigns its return value to the selectedOptions variable. Further down the doPost() method, the code traverses the selectedOptions array and prints the selected values in the browser.
If no checkboxes are clicked, the request.getParameterValues() method will return null. Therefore, it's a good idea to check for null before attempting to traverse through this method's return values.
Before this new servlet can be deployed, the following lines need to be added to the application's web.xml file:
<servlet>
<servlet-name>MultipleValueFieldHandlerServlet</servlet-name>
<servlet-class>
net.ensode.glassfishbook.formhandling.MultipleValueFieldHand lerServlet
</servlet-class>
</servlet>
We would also need to add the following lines of code:
<servlet-mapping>
<servlet-name>MultipleValueFieldHandlerServlet</servlet-name>
<url-pattern>/multiplevaluefieldhandlerservlet</url-pattern>
</servlet-mapping>
These lines assign a logical name and URL to the new servlet.
After re-creating the formhandling.war
file by adding the compiled servlet and the HTML file and redeploying
it, we can see the changes in action by typing the following URL in the
browser window: http://localhost:8080/formhandling/multiplevaluedataentry.html.
After submitting the form, control goes to our servlet and the browser window should look something like this:
Of course, the actual message seen in the browser window will depend on which checkboxes the user clicked on.