No matter how complex a web page looks, the process is always the same: the browser sends a request to the server, and the server sends a response back. It’s part of the HTTP protocol. Even AJAX uses the same principle.
A servlet is a Java class capable of processing a request and generating a response. All we need to do is create a class that inherits from the HttpServlet class.
Servlets are executed by a web container (aka servlet container) that is in charge of creating an instance of the class and calling the necessary methods to serve the request.
Through a web.xml file, we can inform the container what URL should be used to access the servlet.
In this post, we’ll build a little servlet. We’ll use NetBeans, only because when we installed NetBeans, we also installed the Tomcat and GlassFish servers. Both of these are web containers we can use to host our servlet.
In another post, we’ll see how to use Eclipse, but the steps are pretty much the same in any IDE you use.
Open NetBeans and create a new project (File -> New Project).
Select Java Web from the Categories list. In the Projects list, select Web Application. Click on Next.
In the following screen, you can name the project and choose a location.
I’ve named my project ServletSample. Click on Next.
In the next screen is where we choose the server we want to use with our project, as well as the version of Java.
We also define a Context Path for the web application. This is the base of the URL to access the application. At the end of this sample you’ll see how this is used in the URL.
I’ll use the Tomcat server and Java 5. And I’ll use the default context path. Click on Next.
This screen lets us choose different framework that could help us build more complex web applications quickly.
We won’t use any framework for this sample. Click on Finish.
At this point, we have a web application with a single page: index.jsp. We’ll talk about JSP on another post.
We’re ready to create a servlet. But first, let’s create a couple of classes for our business layer.
Add a new Java Class to the project: right-click on the project -> New -> Java Class.
Name the class Product and type ServletSample.Business in the Package field. Click on Finish.
Let’s add a few properties and constructors to the new class.
package ServletSample.Business; public class Product { private int id; private String name; private float price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public Product(){ this.id = -1; this.name = ""; this.price = 0f; } public Product(int id, String name, float price) { this.id = id; this.name = name; this.price = price; } }
Tip: after you define the private field, you can have NetBeans auto-generate the get and set methods by right-clicking on the variable name -> Refactor -> Encapsulate Fields.
This class will represent a product in our application.
Add another class to the project, name it ProductService and place it in the ServletSample.Business package as well.
Let’s add a couple of methods to this class.
package ServletSample.Business; import java.util.List; import java.util.ArrayList; public class ProductService { public List<Product> getProducts(){ List<Product> products = new ArrayList<Product>(); products.add(new Product(1,"HP Laptop",799f)); products.add(new Product(2,"IBM Desktop",599f)); products.add(new Product(3,"Cannon Printer",159f)); return products; } public Product getProduct(int id) { Product product = null; switch(id) { case 1: product = new Product(1,"HP Laptop",799f); break; case 2: product = new Product(2,"IBM Desktop",599f); break; case 3: product = new Product(3,"Cannon Printer",159f); break; } return product; } }
The first method returns a list of products, while the second method returns a specific product. In a real application, these methods would probably make a call to a database.
Now let’s add a new servlet to our project: right-click on the project -> New -> Servlet.
Remember, a servlet is just a Java class the inherits from HttpServlet. Name the new class ProductServlet. Let’s create this class in the ServletSample.Web package. Click on Next.
The next screen allows us to configure the servlet. It’ll take care of adding the servlet definition to the web.xml file.
Change the URL Pattern as shown above. This is the URL portion after the context path that we’ll use to access the servlet from the browser. Click on Finish.
After a little bit of cleaning, the new servlet looks like this:
package ServletSample.Web; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProductServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
When a GET request is made to the servlet, the doGet method is called by the container. Similarly, the doPost method is called when a POST request is made. This means that we can have different logic for each type of request. If we don’t want to support a request type, all we need to do is remove the corresponding method.
In this case, the same code is executed for both types of request, so in both methods we call the processRequest method.
Both methods take a request object that allows us to get information about the request made by the browser, such as parameters and cookies.
They also take a response object that allows us to generate the response to be sent to the browser. You’ll notice we call the getWriter method to create a PrintWriter object. We’ll use this object to write our HTML response.
Let’s add our code to generate a web page inside processRequest.
package ServletSample.Web; import ServletSample.Business.Product; import ServletSample.Business.ProductService; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ProductServlet extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ProductService service = new ProductService(); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { String value = request.getParameter("id"); if (value != null) { int id = Integer.parseInt(value); Product product = service.getProduct(id); out.println("<h1>Product Details</h1>"); out.printf("<div>ID: %d</div>", product.getId()); out.printf("<div>Name: %s</div>", product.getName()); out.printf("<div>Price: $ %.2f</div>", product.getPrice()); out.printf("<div><a href=\"product\">Go Back</a></div>", product.getId()); } else { out.println("<h1>Product List</h1>"); out.println("<table>"); out.println("<tr><td><b>Name</b></td><td><b>Options</b></td></tr>"); for (Product product : service.getProducts()) { out.println("<tr>"); out.printf("<td>%s</td>", product.getName()); out.printf("<td><a href=\"product?id=%d\">Details...</a></td>", product.getId()); out.println("</tr>"); } out.println("</table>"); } } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } }
First we create an instance of the ProductService class.
With the getParameter method of the request object, we obtain the value of a parameter named id. If such parameter was sent by the navigator, we show the details of the corresponding product. If the parameter doesn’t exist, we show a list of all the products.
To keep a sample short, we are not validating that the id parameter is in fact a number. The browser treats all parameters as text (String). We’re also not validating that a product with that id exists.
Run the project (F6 if you’re using NetBeans). Enter product at the end of the URL.
We’re not passing a parameter in the URL, so the list of products will come up.
Each link is a link to the servlet, but with the corresponding parameter. Click on one of the links.
You can click on the link to go back to the product list.
Please leave a comment if you have any question or suggestion.