Sample Maven Java Web Application Project with: MySQL - Servlets - JSP - JSTL and Tomcat

Let's go!

So this is the structure of the project:

And the database:
mysql> use books;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> SHOW TABLES;
+-----------------+
| Tables_in_books |
+-----------------+
| AUTHOR          |
| BOOK            |
| CATEGORY        |
+-----------------+
3 rows in set (0.00 sec)
 
mysql> DESCRIBE AUTHOR;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| ID         | int(11)     | NO   | PRI | NULL    | auto_increment |
| BOOK_ID    | int(11)     | NO   | MUL | NULL    |                |
| FIRST_NAME | varchar(20) | NO   |     | NULL    |                |
| LAST_NAME  | varchar(20) | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)
 
mysql> DESCRIBE BOOK;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| ID          | int(11)     | NO   | PRI | NULL    | auto_increment |
| CATEGORY_ID | int(11)     | NO   | MUL | NULL    |                |
| BOOK_TITLE  | varchar(60) | NO   |     | NULL    |                |
| PUBLISHER   | varchar(60) | NO   |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
 
mysql> DESCRIBE CATEGORY;
+----------------------+-------------+------+-----+---------+----------------+
| Field                | Type        | Null | Key | Default | Extra          |
+----------------------+-------------+------+-----+---------+----------------+
| ID                   | int(11)     | NO   | PRI | NULL    | auto_increment |
| CATEGORY_DESCRIPTION | varchar(20) | NO   |     | NULL    |                |
+----------------------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

Let's see the code:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
 
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>groupId</groupId>
    <artifactId>BooksOne</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <packaging>war</packaging>
    <name>books-app</name>
 
    <url>http://maven.apache.org</url>
 
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
 
    <build>
        <finalName>shop-cart</finalName>
    </build>
 
</project>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
 
<web-app 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"
         version="3.0">
 
    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <page-encoding>UTF-8</page-encoding>
            <scripting-invalid>true</scripting-invalid>
            <include-prelude>/header.jsp</include-prelude>
            <include-coda>/footer.jsp</include-coda>
            <trim-directive-whitespaces>true</trim-directive-whitespaces>
            <default-content-type>text/html</default-content-type>
        </jsp-property-group>
    </jsp-config>
 
    <welcome-file-list>
        <welcome-file>/home.jsp</welcome-file>
    </welcome-file-list>
 
</web-app>

Book.java
/* User: koray@tugay.biz Date: 26/06/15 Time: 17:20 */
 
import java.util.List;
 
public class Book {
 
    private Long id;
    private Long categoryId;
    private String bookTitle;
    private List<Author> authors;
    private String publisherName;
 
    // Getters, setters, toString...
}

Author.java
package biz.tugay.books.model;
/* User: koray@tugay.biz Date: 26/06/15 Time: 17:20 */
 
public class Author {
 
    private Long id;
    private Long bookId;
    private String firstName;
    private String lastName;
 
    // Getters, setters, toString...
}

Category.java
package biz.tugay.books.model;
/* User: koray@tugay.biz Date: 26/06/15 Time: 17:19 */
 
public class Category {
 
    private Long id;
    private String categoryDescription;
 
    // Getters, setters, toString...
}

BookDao.java
package biz.tugay.books.dao;
/* User: koray@tugay.biz Date: 26/06/15 Time: 17:22 */
 
import biz.tugay.books.model.Book;
import biz.tugay.books.model.Category;
 
import java.util.List;
 
public interface BookDao {
    public List<Book> findAllBooks();
    public List<Book> searchBookByKeyword(String keyword);
    public List<Category> findAllCategories();
}

BookDaoImpl.java
package biz.tugay.books.dao;
/* User: koray@tugay.biz Date: 26/06/15 Time: 17:24 */
 
import biz.tugay.books.model.Author;
import biz.tugay.books.model.Book;
import biz.tugay.books.model.Category;
 
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
 
public class BookDaoImpl implements BookDao {
 
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            System.exit(-1);
        }
    }
 
    private Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/books", "root", "");
    }
 
    private void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException ignored) {
            }
        }
    }
 
    @Override
    public List<Book> findAllBooks() {
        List<Book> books = new ArrayList<Book>();
        String sql = "SELECT * FROM book INNER JOIN author ON book.id = author.book_id";
        Connection connection = null;
        try {
            connection = getConnection();
            ResultSet resultSet = connection.prepareStatement(sql).executeQuery();
            while (resultSet.next()) {
                books.add(createBookFromResult(resultSet));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeConnection(connection);
        }
        return books;
    }
 
    @Override
    public List<Book> searchBookByKeyword(String keyword) {
        List<Book> booksByKeyword = new ArrayList<Book>();
 
        String sql = "SELECT * FROM book INNER JOIN author ON book.id = author.book_id"
                + " WHERE book_title like '%"
                + keyword.trim() + "%'"
                + " or first_name like '%"
                + keyword.trim()
                + "%'"
                + " or last_name like '%" + keyword.trim() + "%'";
 
        Connection connection;
 
        try {
            connection = getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Book bookFromResult = createBookFromResult(resultSet);
                booksByKeyword.add(bookFromResult);
            }
        } catch (SQLException ignored) {
        }
 
        return booksByKeyword;
    }
 
    @Override
    public List<Category> findAllCategories() {
        List<Category> categories = new ArrayList<Category>();
        String sql = "SELECT * FROM category";
 
        Connection connection = null;
 
        try {
            connection = getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Category category = new Category();
                category.setId(resultSet.getLong("id"));
                category.setCategoryDescription(resultSet.getString("category_description"));
                categories.add(category);
            }
        } catch (SQLException e) {
 
        } finally {
            closeConnection(connection);
        }
        return categories;
    }
 
    private Book createBookFromResult(ResultSet resultSet)
            throws SQLException {
        List<Author> authorList = new ArrayList<Author>();
        Book book = new Book();
        Author author = new Author();
        book.setId(resultSet.getLong("id"));
        book.setBookTitle(resultSet.getString("book_title"));
        book.setCategoryId(resultSet.getLong("category_id"));
        author.setBookId(resultSet.getLong("book_Id"));
        author.setFirstName(resultSet.getString("first_name"));
        author.setLastName(resultSet.getString("last_name"));
        authorList.add(author);
        book.setAuthors(authorList);
        book.setPublisherName(resultSet.getString("publisher"));
        return book;
    }
 
}

BookServlet.java
package biz.tugay.books;
/* User: koray@tugay.biz Date: 27/06/15 Time: 11:18 */
 
import biz.tugay.books.dao.BookDao;
import biz.tugay.books.dao.BookDaoImpl;
import biz.tugay.books.model.Book;
import biz.tugay.books.model.Category;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
@WebServlet(
        name = "bookServlet", urlPatterns = {"/books"},
        initParams = {
                @WebInitParam(name = "base", value = "/bookWeb/books"),
                @WebInitParam(name = "imageURL", value = "/bookWeb/images")
        }
)
 
public class BookServlet extends HttpServlet {
 
    @Override
    public void init() throws ServletException {
        BookDao bookDao = new BookDaoImpl();
        List<Category> categoryList = bookDao.findAllCategories();
        getServletContext().setAttribute("categoryList", categoryList);
        System.out.println(categoryList);
    }
 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
 
        String action = req.getParameter("action");
 
        if (action == null) {
            req.getRequestDispatcher("/home.jsp").forward(req, resp);
            return;
        }
 
        if (action.equals("allBooks")) {
            handleAllBooks(req, resp);
            return;
        }
 
        if (action.equals("category")) {
            String categoryId = req.getParameter("categoryId");
            handleCategory(categoryId, req, resp);
            return;
        }
 
        if (action.equals("search")) {
            String keyword = req.getParameter("keyword");
            handleByKeyword(keyword, req, resp);
            return;
        }
 
    }
 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req, resp);
    }
 
    private void handleByKeyword(String keyword, HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        BookDao bookDao = new BookDaoImpl();
        List<Book> booksByKeyword = bookDao.searchBookByKeyword(keyword);
        req.setAttribute("bookList", booksByKeyword);
        req.getRequestDispatcher("/listOfBooks.jsp").forward(req, resp);
    }
 
    private void handleCategory(String categoryId, HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        BookDao bookDao = new BookDaoImpl();
        List<Book> books = bookDao.findAllBooks();
        List<Book> booksByCategory = new ArrayList<Book>();
        for (Book book : books) {
            if (book.getCategoryId().toString().equals(categoryId)) {
                booksByCategory.add(book);
            }
        }
        req.setAttribute("bookList", booksByCategory);
        req.getRequestDispatcher("/listOfBooks.jsp").forward(req, resp);
    }
 
    private void handleAllBooks(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        BookDao bookDao = new BookDaoImpl();
        List<Book> bookList = bookDao.findAllBooks();
        req.setAttribute("bookList", bookList);
        req.getRequestDispatcher("/listOfBooks.jsp").forward(req, resp);
    }
 
}

header.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html >
<html>
<head>
    <link rel="stylesheet" href="resources/css/bookstore.css" type="text/css"/>
    <script type="text/javascript" src="resources/js/jquery-1.9.1.js"></script>
    <script src="resources/js/bookstore.js"></script>
</head>
<body>
<div id="centered">
    <div class="header">
        <h2>
  <span style="margin-left: 15px; margin-top: 15px; " class="label">BOOK
   <span style="color: white;">STORE</span></span>
        </h2>
    </div>
    <%@ include file="/leftColumn.jsp" %>

footer.jsp
</div>
</body>
</html>

home.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<br/>
<span class="label">Featured Books</span>
<table>
    <tr>
        <td><img src="<c:url value='resources/images/01.png'/>"></td>
        <td><img src="<c:url value='resources/images/02.png'/>"></td>
        <td><img src="<c:url value='resources/images/03.png'/>"></td>
        <td><img src="<c:url value='resources/images/04.png'/>"></td>
        <td><img src="<c:url value='resources/images/05.png'/>"></td>
    </tr>
    <tr>
        <td><img src="<c:url value='resources/images/06.png'/>"></td>
        <td><img src="<c:url value='resources/images/07.png'/>"></td>
        <td><img src="<c:url value='resources/images/08.png'/>"></td>
        <td><img src="<c:url value='resources/images/09.png'/>"></td>
        <td><img src="<c:url value='resources/images/10.png'/>"></td>
    </tr>
</table>

leftColumn.jsp
<div class="leftbar">
    <ul id="menu">
        <li>
            <div>
                <a class="link1" href="<c:url value="/books"/>">
                    <span class="label" style="margin-left: 15px;">Home</span>
                </a>
            </div>
        </li>
        <li>
            <div>
                <a class="link1"
                   href="<c:url value="/books"><c:param name="action" value="allBooks"/></c:url>">
                    <span style="margin-left: 15px;" class="label">
                        All Books
                    </span>
                </a>
            </div>
        </li>
        <li>
            <div>
                <span class="label" style="margin-left: 15px;">
                    Categories
                </span>
            </div>
            <ul>
                <li>
                    <a class="label" href="#">
                        <span class="label" style="margin-left: 30px;">
                            <a href="
                            <c:url value="/books">
                            <c:param name="action" value="category"/>
                            <c:param name="categoryId" value="1"/>
                            </c:url>
                            ">Clojure</a>
                        </span>
                    </a>
                </li>
                <li>
                    <a class="label" href="#">
                        <span class="label" style="margin-left: 30px;">
                            <a href="
                            <c:url value="/books">
                            <c:param name="action" value="category"/>
                            <c:param name="categoryId" value="2"/>
                            </c:url>
                            ">Groovy</a>
                        </span>
                    </a>
                </li>
                <li>
                    <a class="label" href="#">
                        <span class="label" style="margin-left: 30px;">
                            <a href="
                            <c:url value="/books">
                            <c:param name="action" value="category"/>
                            <c:param name="categoryId" value="3"/>
                            </c:url>
                            ">Java</a>
                        </span>
                    </a>
                </li>
                <li>
                    <a class="label" href="#">
                        <span class="label" style="margin-left: 30px;">
                            <a href="
                            <c:url value="/books">
                            <c:param name="action" value="category"/>
                            <c:param name="categoryId" value="4"/>
                            </c:url>
                            ">Scala</a>
                        </span>
                    </a>
                </li>
            </ul>
        </li>
        <li>
            <div>
                <span class="label" style="margin-left: 15px;">Contact Us</span>
            </div>
        </li>
    </ul>
    <form class="search" method="post" action="<c:url value="/books" />">
        <input type="hidden" name="action" value="search"/>
        <input id="text" type="text" name="keyword" size="12"/>
        <span class="tooltip_message">?</span>
 
        <p/>
        <input id="submit" type="submit" value="Search"/>
    </form>
 
</div>

listOfBooks.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div>
    <span class="label" style="margin-left: 15px;">List of All Books</span>
</div>
 
<table id="grid">
    <thead>
    <tr>
        <th id="th-title">Book Title</th>
        <th id="th-author">Author</th>
        <th id="th-publisher">Publisher</th>
    </tr>
    </thead>
    <%--@elvariable id="book" type="biz.tugay.books.model.Book"--%>
    <tbody>
        <c:forEach items="${requestScope.bookList}" var="book">
            <tr>
                <td>${book.bookTitle}</td>
                <c:forEach items="${book.authors}" var="author">
                    <td>${author.firstName}&nbsp;${author.lastName} </td>
                </c:forEach>
                <td>${book.publisherName}</td>
            </tr>
        </c:forEach>
    </tbody>
</table>