Java EE Servlet/JSP tutorial: Building a simple listing in JSP

From Resin 4.0 Wiki

Revision as of 00:00, 27 April 2012 by Rick (Talk | contribs)
Jump to: navigation, search

Building a simple listing in JSP and Servlets. This tutorial is part of Java_EE_Tutorial_covering_JSP_2.2,_and_Servlets_3.0.

Assuming very little knowledge of HTML, Java and JSP, you can get started with Java Servlets and JSP (Java Server Pages) quite easily.

First step is getting Eclipse WTP and getting the Resin 4.0 runtime.

Contents

Getting started Eclipse Java EE

Feel free to use whatever IDE you would like. If you are new to Java and/or Java development, I suggest starting with Eclipse. It is the dominant IDE mindshare wise. IntelliJ is a great option as well.

Any IDE that supports Java EE will support creating a war file. The war file is a binary distribution file that you can copy to Resin and Resin will automatically deploy your web application (war is short for web application archive file).


First go here to get Eclipse for Java EE: Install Guide for Eclipse for Java EE Indigo or higher.


Using Eclipse Indigo or higher

Install Resin plugin:

  1. Go to File menu -> New Project -> Dynamic Web Project
  2. In New Dynamic Web Project Dialog-> New Runtime...
  3. In New Runtime Dialog -> Download Additional Server Adapters -> Select Resin (Java EE Web Profile) 4.0.x
  4. (Click Next and Ok until it installs Resin runtime)
  5. (Eclipse needs to restart)


Setup new Web Project in Eclipse

  1. File -> New Project -> Dynamic Web Project
  2. In New Dynamic Web Project Dialog-> New Runtime...->Select Resin->Check create local server checkbox
  3. Step 2 of New Runtime...->Click Download and Install (you only have to do this once)
  4. Fill out project name etc. (bookstore).
  5. (Click Next and Ok until you are done)


What is going to be in the project

The prjoject will be a basic CRUD (create read update delete) listing for a BookStore.

Creating model and Repository objects for books

Create a new Java class as follows:

Eclipse: Right Click "Java Resources" in Project Explorer -> New -> Class -> Package com.bookstore -> Class Name -> Book (That is the last time I will tell you how to create a class in Eclipse.)

Add title, description, price, pubDate and id properties as follows as well as a toString method for debugging:

Book model class

package com.bookstore;

import java.math.BigDecimal;
import java.util.Date;

public class Book implements Cloneable {

	private String title; 
	private String description;
	private BigDecimal price;
	private Date pubDate;
	private String id;
	
	public Book(String id, String title, String description, BigDecimal price, Date pubDate) {
		this.id = id;
		this.title = title;
		this.description = description;
		this.price = price;
		this.pubDate = pubDate;
	}
	
	public Book () {
		
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public BigDecimal getPrice() {
		return price;
	}

	public void setPrice(BigDecimal price) {
		this.price = price;
	}

	public Date getPubDate() {
		return pubDate;
	}

	public void setPubDate(Date pubDate) {
		this.pubDate = pubDate;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}
	
	public Book cloneMe()  {
		try {
			return (Book) super.clone();
		} catch (CloneNotSupportedException e) {
			return null;  
		}
	}
	
	@Override
	public String toString() {
		return "Book [title=" + title + ", description=" + description
				+ ", price=" + price + ", pubDate=" + pubDate + ", id=" + id
				+ "]";
	}

}

If you are new to Java and the above seems foreign to you, I suggest you read up on Java a bit Official Java tutorial. Read the first three trails (Getting Started, Learning the Java Language and Essential Java Classes), and then skip ahead to Java Beans. Skimming is ok. If you have programmed before, most things you will pick up on your own.

Reminder: The methods public String getId() and public void setId(String id) would define a property called id.

This first tutorial is not going to actually talk to a database or use JDBC. For now, we are just going to use the collection API to create a Repository object (some people call this a DAO -- data access object). The Repository object encapsulates how an object gets persisted, queried and updated (CRUD operations).

We know we are going to later use JDBC/RDBMS (MySQL), JTA/RDBMS, JCache, MongoDB, etc. instead of the collection API so let's define an interface so we can swap these in quickly. The interface will define the contract with our Repository object that we can later swap out with other implementations.

Eclipse: Right Click "Java Resources" in Project Explorer -> New -> Class -> Package com.bookstore -> Class Name -> Book (That is the last time I will tell you how to create a class in Eclipse.)


BookRepository interface

package com.bookstore;

import java.util.List;

public interface BookRepository {
	Book lookupBookById(String id);

	void addBook(String title, String description,
			String price, String pubDate);

	void updateBook(String id, String title,
			String description, String price, String pubDate);
	
	void removeBook(String id);


	List<Book> listBooks();

}

Create a class called BookRepositoryImpl as follows:

package com.bookstore;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.math.BigDecimal;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class BookRepositoryImpl implements BookRepository {

	private SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
	private int count;
	private Map<String, Book> idToBookMap = new HashMap<String, Book>();

	public BookRepositoryImpl()  {
		synchronized (this) {
			books(book("War and Peace", "blah blah blah", "5.50", "5/29/1970"),
					book("Pride and Prejudice", "blah blah blah", "5.50", "5/29/1960"),
					book("book1", "blah blah blah", "5.50", "5/29/1960"),
					book("book2", "blah blah blah", "5.50", "5/29/1960"),
					book("book3", "blah blah blah", "5.50", "5/29/1960"),
					book("book4", "blah blah blah", "5.50", "5/29/1960"),
					book("book5", "blah blah blah", "5.50", "5/29/1960"),
					book("book6", "blah blah blah", "5.50", "5/29/1960"),
					book("book7", "blah blah blah", "5.50", "5/29/1960"),
					book("book8", "blah blah blah", "5.50", "5/29/1960"),
					book("book9", "blah blah blah", "5.50", "5/29/1960"),
					book("Java for dummies", "blah blah blah", "1.99", "5/29/1960"));
		}
	}

	private Book book(String title, String description, String aPrice,
			String aPubDate)  {

		Date pubDate = null;
		BigDecimal price = null;
		
		try {
			price = new BigDecimal(aPrice);
		}catch (Exception ex) {
		}
		
		try {
			pubDate = dateFormat.parse(aPubDate);
		}catch (Exception ex) {
		}
		
		return new Book("" + (count++), title, description, price, pubDate);
		
	}

	private void books(Book... books) {
		for (Book book : books) {
			doAddBook(book);
		}
	}

	private void doAddBook(Book book) {
		synchronized (this) {
			this.idToBookMap.put(book.getId(), book);
		}
	}

	@Override
	public Book lookupBookById(String id)  {
		synchronized (this) {
			return this.idToBookMap.get(id).cloneMe();
		}
	}

	@Override
	public void addBook(String title, String description, String price,
			String pubDate)  {
		doAddBook(book(title, description, price, pubDate));
	}

	@Override
	public void updateBook(String id, String title, String description,
			String price, String pubDate) {
		Book book = book(title, description, price, pubDate);
		synchronized (this) {
			book.setId(id);
			this.idToBookMap.put(id, book);
		}
	}

	private List<Book> doListBooks()  {
		List<Book> books;
		synchronized (this) {

			books = new ArrayList<Book>(this.idToBookMap.size());
			for (Book book : this.idToBookMap.values()) {
				books.add(book.cloneMe());
			}
		}
		return books;
	}
	
	public List<Book> listBooks() {
		
		List<Book> books = doListBooks();

		Collections.sort(books, new Comparator<Book>() {
			public int compare(Book bookA, Book bookB) {
				return bookA.getId().compareTo(bookB.getId());
			}
		});
		return books;
	}

	@Override
	public void removeBook(String id)  {
		synchronized(this) {
			this.idToBookMap.remove(id);
		}
	}

}

This is a fairly basic class. It is largely based on the collections API. You can find out more information about the Java collections API at this tutorial trail. A full discussion of the collection API is out of scope for this tutorial, and this class is mainly just for testing, later we will store items in the databases and such.

One interesting thing to note is the use of this new Java EE annotation @ApplicationScoped. Annotations allow you to add meta-data to Java objects. (To learn more about annotations see this annotations tutorial.).

The ApplicationScoped specifies that a bean is application scoped. Scoping defines a lifecycle for how long an object will be around. ApplicationScoped means it will be around for the complete lifecycle of the Web Application. This annotations has slightly different meanings depending on whether it is used with EJBs or Servlets. This annotation is part of the CDI support added to Java EE 6 to handle Java Dependency Injection. To learn more about CDI go see this tutorial Java Dependency Injection and this one part 2 both written by the same author that is writing this tutorial now. :)

Now that we have a model (Book, BookRepository), lets define our web controller (Servlet) and view (JSPs).

Creating your first Servlet

package com.bookstore.web;

import java.io.IOException;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bookstore.BookRepository;

@WebServlet("/book/")
public class BookListServlet extends HttpServlet {
	
	@Inject 
	private BookRepository bookRepo;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("books", bookRepo.listBooks());
		getServletContext().getRequestDispatcher("/book-list.jsp").forward(request, response);
	}

}


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix ="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">


<html>
<head>
<title>Book listing</title>
</head>
<body>

<a href="${pageContext.request.contextPath}/book">Add Book</a>

<table>
	<tr>
		<th>Title</th>
		<th>Description</th>
		<th>Price</th>
		<th>Publication Date</th>
	</tr>
	
	<c:forEach var="book" items="${books}">
		<tr>
			<td><a href="${pageContext.request.contextPath}/book?id=${book.id}">${book.title}</a></td>
			<td>${book.description}</td>
			<td>${book.price}</td>
			<td>${book.pubDate}</td>
		</tr>
	</c:forEach>
</table>

</body>
</html>
Personal tools
TOOLBOX
LANGUAGES