Introducing Java Web Development
The mind, once stretched by a new idea, never returns to its original dimensions.
—Ralph Waldo Emerson
An intelligent machine is that which extends the very imagination with which it was built. An example of this is the instruction called invokeDynamic,1 which was introduced with Java 7 to optimize the performance of dynamically typed languages on the Java Virtual Machine (JVM). The JVM, originally intended for Java, can now host a myriad of programming languages, including Groovy2 and Scala.3 This has led to a renaissance of Java web development. This new paradigm of cross-pollination and diverse, well-founded options carves out a number of niches in the Java ecosystem, resulting in a richer web landscape than ever before.
The open source community has capitalized on the multiparadigm capabilities offered by the languages that run on the JVM, by means of web frameworks, to dramatically enhance the productivity in web development. Java EE4 advanced this momentum, pioneered by Java frameworks such as Spring,5 by standardizing and improving the API and runtime environment. Further, functional programming constructs, in the form of lambdas, have been added to Java 8. As a result, Java is on the rebound to become an übersolution.
This chapter sets the stage for the book by introducing the three key players that join forces in building modern Java web applications: the JVM languages, Java EE, and the Java web frameworks.
Note The JVM languages represent a new category of languages that run on the JVM. With the latest version, Java 8, Java is no longer a privileged JVM language and is now simply one of the many languages that run on the JVM.
The chapter begins by introducing the JVM languages and then introduces Java EE. The Java EE platform is the set of API specifications that act as the building blocks for developing web applications. The chapter then highlights the Java web frameworks, which will be the subject of the book from Chapter 4 onward.
The JVM is the runtime environment that provides you with the ability to use different programming languages for building web applications. The JVM languages can be largely classified into two types: languages that are designed for the JVM and existing languages that are ported to JVM.
Languages Designed for the JVM
Plenty of languages are specifically designed for the JVM; Table 1-1 describes a few of them. All but Clojure are discussed in this book.
Table 1-1. Languages Designed for the JVM
Language Designed for JVM |
Description |
---|---|
Clojure6 |
Clojure is a dynamically typed, functional language. |
Groovy |
Groovy is a dynamic, compiled language with syntax similar to Java but is more flexible. |
Java |
Java is a statically typed, imperative language. The latest release of Java, Java 8, supports aspects of functional programming. |
Scala |
Scala is a statically typed, compiled language that supports aspects of functional programming and performs a large amount of type inference, much like a dynamic language. |
Here are some important definitions:
Figure 1-1 shows where Java 8, Groovy, Scala, and Clojure fall on the functional language continuum. Java 8 introduces lambdas, which makes it slightly functional, Groovy has had functional constructs since its inception and is even more functional with Groovy 2.0, and Scala is the most functional of the three object-oriented (OO) languages. Clojure, on the other hand, is a purely functional, non-OO language.
Figure 1-1. Functional gradation of JVM languages
Note In Figure 1-1, no version number is mentioned for Groovy, Scala, and Clojure because Java supports aspects of functional programming starting from Java 8 only.
Languages Ported to the JVM
JRuby, Jython, and Rhino are a few of the mainstream JVM implementations of existing languages. Table 1-2 describes them.
Table 1-2. Languages Ported to the JVM
Languages Ported to JVM |
|
---|---|
JRuby7 |
JRuby is a JVM reimplementation of the Ruby programming language. Ruby is a dynamically typed OO language with some functional features. |
Jython8 |
Jython is a reimplementation of Python on the JVM, so it is a dynamic language. |
Rhino9 |
Rhino provides an implementation of JavaScript on the JVM. JavaScript is a dynamically typed OO language. |
This book is based on some of the mainstream object-oriented JVM languages that were specifically designed for the JVM, namely, Java, Groovy, and Scala.
Java began life as a programming language designed for building stand-alone applications and grew rapidly into other spheres. A large part of Java’s popularity can be attributed to its usage in creating web applications. A web application consists of static and dynamic (interactive) web pages. Static web pages contain various types of markup languages (HTML, XHTML, and so on) and are used, in general, to provide information; dynamic web pages, on the other hand, are capable of generating content with the aid of additional web components (covered in Chapter 2). Thus, a web application is a collection of web pages and is capable of generating dynamic content in response to requests. Unlike a web page used merely to provide information, a web application lets you perform some activity and save the result. Developing a web application, however, is fundamentally different from building stand-alone applications and requires you to understand the following three key elements:
Note There are several types of containers, but this book will focus on the web container primarily used for web applications. You have to choose the container based on the kind of application you want to develop.
The Java EE Platform
The Java EE platform is driven by the following two goals:
Figure 1-2 summarizes the evolution of Java EE and, for the sake of brevity, shows only the new specifications added with each release.
Figure 1-2. The evolution of Java EE
Note Pruning (also known as marked for deletion) consists of a list of proposed features for possible removal in the next Java EE release in order to reduce the size of the platform or to keep it from bloating.
The goal of Web Profile is to allow developers to create web applications with the appropriate set of technologies.
The Java EE platform is aimed at standardizing and reducing the complexity of enterprise application development by providing an application model that defines an architecture for implementing services as multitiered applications. In a multitiered application, the functionality of the application is separated into distinct functional areas, called tiers. Figure 1-3 illustrates the typical multitiered architecturein a Java EE application model.
Figure 1-3. Multitier architecture in Java
The client tier is the top tier in a multitiered Java EE architecture; it consists of application clients that make requests to the Java EE server, which is often located on a different machine. The server processes the requests and returns a response to the client. An example of a client is a web browser or a stand-alone application.
The web tier consists of components that handle the interaction between clients and the business tier. After receiving a request from the client, the web tier does the following:
As shown in Figure 1-2, a new Web Profile specification has been added in Java EE 7.10 Table 1-3 lists technologies included in the Web Profile specification. As mentioned earlier, the goal of Web Profile is to allow developers to create web applications with the appropriate set of technologies.
Table 1-3. Web Profile 7 Specification
Specification |
Version |
URL |
---|---|---|
JSF |
2.2 |
|
JSP |
2.3 |
|
JSTL |
1.2 |
|
Servlet |
3.1 |
|
WebSocket |
1.0 |
|
Expression Language |
3.0 |
|
EJB Lite |
3.2 |
|
JPA |
2.1 |
|
JTA |
1.2 |
|
Bean Validation |
1.1 |
|
Managed Beans |
1.0 |
|
Interceptors |
1.2 |
|
Contexts and Dependency Injection |
1.1 |
|
Dependency Injection for Java |
1.0 |
|
Debugging Support for Other Languages |
1.0 |
|
JAX-RS |
2.0 |
|
JSON-P |
1.0 |
Regarding the Web Profile specifications listed in Table 1-3:
This book concentrates on the web tier of Java EE; we will dive deep into the web tier in Chapter 2.
The multitier architecture of Java EE has a tremendous impact on the development of Java enterprise applications. A Java enterprise applicationcan be defined as a Java application that utilizes the enterprise services offered by Java EE. In fact, a web application can be classified as an enterprise application if it utilizes Java EE services in the form of components packed in the web tier. Java EE isolates these services functionally into separate tiers, as illustrated in Figure 1-3, by providing an application model on which the Java enterprise applications should be built. As a consequence, the Java enterprise application mirrors the multitier architecture of Java EE. Figure 1-4 illustrates a generalized view of the layers of a typical web application.
Figure 1-4. A generalized view of layers in an enterprise application
Each layer in Figure 1-4 is an area of concern, for the application. For instance, the web layer deals only with employing the web tier components of Java EE. Having different layers in an application results in what is called a separation of concerns. In terms of implementation, this separation of concerns is achieved using coarse-grained interfaces.
The concern is the feature, functionality or business functions with which the application’s developer needs to be concerned. Crosscutting such concerns is inherent in complex systems and leads to code scattering, which is when code for one concern spans many modules, and code tangling, which is when code in one module concentrates on addressing multiple concerns. Code scattering and code tangling lead to a lack of clarity, redundancy, rigidity, and continuous refactoring. Figure 1-5 illustrates how the system services of logging, transaction, and security crosscut the business functions of the application.
Figure 1-5. BookService involved with system services
BookService in Figure 1-5 is too involved with the system services. Each object knows and is responsible for logging, security, and transaction. A method, for example, to purchase a book in BookService should be concerned only with how to purchase the book and not with whether it is secure or transactional. Separation of concerns, one of the main goals of software engineering, lets you handle each service on its own and thereby does the following:
SEPARATION OF CONCERNS
The term separation of concerns (SoC) was coined by Edsger W. Dijkstra in his paper “On the role of scientific thought.”11 Dijkstra explains in in the following terms:
Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one’s subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained—on the contrary!—by tackling these various aspects simultaneously. It is what I sometimes have called “the separation of concerns,” which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts, that I know of. This is what I mean by “focusing one’s attention upon some aspect”: it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect’s point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.
The web layer of a web application consists of the web tier components of Java EE such as servlets and JSP. The web layer can access the service layer, but there should not be a tight coupling between the web layer and the service layer. That is, changing the service layer should not impact the web layer.
The service layer consists of the business tier components of Java EE such as Enterprise JavaBeans (EJBs). The service layer can access the data access layer, but there should be no tight coupling between the service layer and the data access layer. In fact, the service layer should not know anything about the web or data access layer. The service layer provides a coarse-grained interface for the web layer.
The data access layer consists of the data tier components of Java EE such as JDBC and JPA. This layer should not contain any business logic. This layer abstracts the actual persistence mechanism (in other words, JDBC or JPA) from the service layer by providing the coarse-grained interface to the service layer.
Note The call flow in this architecture is always from the top layer to the bottom layer. In other words, the service layer should be able to call the data access layer but not vice versa.
In this chapter, you will build the data access layer of the bookstore application and query it via a stand-alone Java application. In Chapter 2, you will replace this stand-alone Java application with a web layer using the web tier components of Java EE (specifically, servlets and JSPs). You will use this data access layer throughout this book, and from Chapter 4 onward you will build a web application repeatedly by rebuilding the web layer using different web frameworks.
Oracle and the Java Community Process (JCP) provide standardized enterprise components, and if successful enterprise applications can be built using these components, then why do we need web frameworks? What are web frameworks for? The next section answers these questions.
While Java EE does a great job of standardizing the enterprise infrastructure, providing an application model, and providing components adequate to develop web applications, two major problems are associated with it.
Frameworks address these two major problems (and several other concerns discussed in detail in Chapter 3). Table 1-4 describes the web frameworks you will learn about in this book.
Table 1-4. JVM-Based Web Frameworks
Web Frameworks |
Language |
Download From |
---|---|---|
Struts 2 |
Java |
|
Spring Web MVC |
Java |
|
JSF 2 |
Java |
|
Grails 2 |
Groovy |
|
Play 2 |
Java and Scala |
Now that you have looked at the three key players that join forces in building modern Java web applications (the JVM languages, Java EE, and the Java web frameworks), it is time to delve into some specifics about Java.
The following section introduces Java so you can build your first stand-alone Java application. Since this book is centered on web development using Java and is not about Java as a programming language, the introduction to Java is brief—it’s just enough to help newcomers to the language follow the subsequent chapters.
Getting Started with Java
A Javaapplication is a computer program that executes when you use the java command to launch the JVM. In the Java programming language, all source code is first written in plain-text files (in Notepad, for instance, or in any text editor) with the .java extension. The source files are compiled by the javac compiler into .class files that contain bytecode instructions. The JVM reads these bytecode instructions and translates them into the machine-language operations that each computer executes. By making the JVM available on many platforms, Sun transformed Java into a cross-platform language. As shown in Figure 1-6, the very same bytecode can run on any operating system for which a JVM has been developed.
Figure 1-6. Cross-platform Java
Because the JVM is available on many different operating systems, the same .class files are capable of running on Windows, Unix, Linux, or Mac OS. In the section that follows, I will show you how to compile and run your first Java application. But first you need to set up the development environment.
Setting Up the Development Environment
The Java software is available in two distributions.
The JRE includes a JVM and the core libraries; it is essentially just an environment for running bytecode. The JDK includes the JRE, a Java compiler (javac), and other tools—the basic software you need to write and compile Java programs.
Before you can start compiling and running Java programs, you need to download and install the JDK and configure some system environment variables.
Most of the code in this book requires Java 7, but some of the code is based on Java 8, so you should install Java 8. To get the latest version of the JDK)), follow these steps:
To confirm you have installed the JDK correctly, type javac on the command line from any directory on your machine. If you see instructions on how to run javac correctly, then you have installed it successfully.
Creating and Running Your First Java Application
This section demonstrates how to create, compile, and execute a simple Java application on Windows. Every Java application has one class that is the program’s starting point (often called an entry point). Listing 1-1 illustrates a HelloWorld entry-point class.
Listing 1-1. A HelloWorld Java Application
1. public class HelloWorld {
2. public static void main(String[] args) {
3. System.out.println("Hello World.");
4. }
5. }
The name of the Java application should be the name of the entry-point class, and the file that holds a Java class must have the same name as the class. Therefore, the HelloWorld class in Listing 1-1 must be stored in a file named HelloWorld.java.
Note Every Java application has only one main method.
You use the javac program in the bin directory of your JDK installation directory to compile Java programs. Assuming you have edited the PATH environment variable on your computer, you should be able to invoke javac from any directory. To compile the HelloWorld class in Listing 1-1, do the following:
javac HelloWorld.java
If everything goes well, javac will create a file named HelloWorld.class in your working directory.
Running Your Java Application
To run your Java application, you have to use the java program that is part of the JDK with the command java <class name>. Again, having added the PATH environment variable, you should be able to invoke java from any directory. From your working directory, type the following:
java HelloWorld
Note that you do not include the .class extension when running a Java application. You will see the following on your console:
Hello World.
Developing Java Applications with an IDE
In this book you will use the Eclipse Kepler integrated development environment (IDE). To download it, follow these steps:
Creating Your First Project in the IDE
After you’ve started Eclipse, you can make a new project as follows:
Figure 1-7. Creating a Java project
To create a class with a main method for your first program, follow these steps:
Figure 1-8. Creating a Java class
A package groups classes together. In the Name field, you can type the name of the class, which is HelloWorld. Select the check box that gives you a main method (public static void main (String args[])). When you’re done, you should have a class similar to the one in Listing 1-2.
Listing 1-2. A Simple Java Application
packageapress.helloworld;
/**
* A Hello World Java application
* @author Vishal Layka
*
*/
public class HelloWorld {
/**
* Entry point
* @paramargs
*/
public static void main(String[] args){
System.out.println("Hello World");
}
}
You can now run the application by clicking the Run button in the toolbar or by choosing Run from the Run menu.
Eclipse then displays a console panel under the code area that shows the output of your program. In this case, it says “Hello World.”
Javadoc Comments
A Javadoc commentbegins with the /** character sequence and ends with the */ character sequence. The compiler ignores everything between these character sequences. In Eclipse, you can add the Javadoc comments by selecting the class or method name and pressing Alt+Shift+J. To see all the shortcuts in Eclipse, press Ctrl+Shift+L.
To generate the Javadoc, select the project in Eclipse, select the Project menu, and click Generate Javadoc, as shown in Figure 1-9.
Figure 1-9. Generating a Javadoc
A window will open (Figure 1-10) where you can select Java projects or their underlying resources for which a Javadoc needs to be generated. Several other options are also available; you can select whether to generate a Javadoc for public/private APIs, and so on. For now, configure the javadoc.exe file in the “Javadoc command” field and browse to and select the target folder where the Javadoc should be generated.
Figure 1-10. Generating a Javadoc
Click Finish. On the console you can see the progress of the Javadoc generation. Figure 1-11 shows the generated Javadoc.
Figure 1-11. Javadoc for the HelloWorld class
Now you will learn how to create a simple but functional version of the stand-alone bookstore application that you’ll work on throughout this book.
Instead of simply declaring one web framework as the best, this book intends to show the strengths of the most popular web frameworks by means of a real-world bookstore application. Developing a complete real application necessitates a seamless collaboration of dynamic functionalities, and the code for building such components is contrived and too involved. Instead of focusing on developing such moving parts, this book confines its attention on leveraging the strengths of each web framework. Throughout the book, you will learn how to use Java EE and the Java web frameworks to build the bookstore web application. In this chapter, you will take the first step by building a traditional stand-alone Java bookstore application. In Chapter 2, you will transform the stand-alone application into a web application.
Throughout this book, I will use a single web application case study to demonstrate how to write a web application using servlets and JSPs and the different web frameworks such as JSF, Struts 2, Spring Web MVC, and rapid web development frameworks such as Grails and Play. The application allows users to view books and search for them by keyword, usually by the first name or last name of the author and the title of the book.
Data Model for the Bookstore Application
This section introduces a simple data model that will be used for the bookstore web application throughout this book. I will expand the model progressively with each chapter, as the need arises. The model is a simple book database that consists of three tables.
Each category can have zero or more books. For instance, there could be zero or more books in the Java category in the bookstore. In other words, there is a one-to-many relationship between the Category and Book tables. Similarly, each book can have one or more authors. In other words, there is a one-to-many relationship between the Book and Author tables. The entity-relationship (ER) diagram in Figure 1-12 illustrates this relationship.
Figure 1-12. Entity-relationship diagram of the data model
This data model is not production-ready because you can have a many-to-many relationship between Category and Book, and you can have a many-to-many relationship between Book and Author. I have kept the data model simple so that the complexity of the data model does not get in the way of learning the mechanics of building a web application. However, you can, for example, model a many-to-many relationship between Book and Author, as illustrated in Figure 1-13.
Figure 1-13. Many-to-many relationship between Book and Author
The sole purpose of the BookAuthor table is to provide a many-to-many relationship between Book and Author.
Note As shown in Figure 1-13, there is a one-to-many relationship between Book and BookAuthor, and there is a one-to-many relationship between Author and BookAuthor. In fact, the sole purpose of the BookAuthor table is to provide a many-to-many relationship between Book and Author—in other words, an author can write many books, and a book can have many authors.
Because of the profusion of web applications across several domains, many relational and nonrelational databases such as NoSQL12 have emerged. In this book, I’ll use MySQL13 because it is the most widely used free database management system (DBMS). To install MySQL, go to http://dev.mysql.com/downloads/ and click Download. You can download MySQL Server 5.5 or newer. You can see the instructions for installing MySQL at http://dev.mysql.com/doc/refman/5.5/en/installing.html.
To create the books database, use the following command:
create database books;
You need to instruct MySQL to create tables in the books database by using the following command:
use books;
Now you can create the tables using the statements illustrated in Listing 1-3.
Listing 1-3. Creating Tables for the Bookstore
CREATE TABLE CATEGORY (
ID INT NOT NULL AUTO_INCREMENT ,
CATEGORY_DESCRIPTION VARCHAR(20) NOT NULL ,
PRIMARY KEY (ID)
);
CREATE TABLE BOOK (
ID INT NOT NULL AUTO_INCREMENT,
CATEGORY_ID INT NOT NULL ,
BOOK_TITLE VARCHAR(60) NOT NULL,
PUBLISHER VARCHAR(60) NOT NULL ,
PRIMARY KEY (ID) ,
CONSTRAINT FK_BOOK_1 FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORY(ID)
);
CREATE TABLE AUTHOR (
ID INT NOT NULL AUTO_INCREMENT ,
BOOK_ID INT NOT NULL ,
FIRST_NAME VARCHAR(20) NOT NULL ,
LAST_NAME VARCHAR(20) NOT NULL ,
PRIMARY KEY (ID) ,
CONSTRAINT FK_AUTHOR_1 FOREIGN KEY (BOOK_ID) REFERENCES BOOK (ID)
);
You can verify the created tables using the show tables command, as illustrated in Figure 1-14.
Figure 1-14. All tables in the database
You can also check the structure of the tables using the command describe <table-name> or desc<table-name>, as illustrated in Figure 1-15.
Figure 1-15. Structure of the tables
Now populate the tables using the insert statements, as follows:
insert into category (category_description) values ('Clojure'),
insert into category (category_description) values ('Groovy'),
insert into category (category_description) values ('Java'),
insert into category (category_description) values ('Scala'),
You can verify the populated Category table as illustrated in Figure 1-16.
Figure 1-16. All categories in the Category table
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (1, 'Practical Clojure', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (2, 'Beginning Groovy, Grails and Griffon', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (2, 'Definitive Guide to Grails 2', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (2, 'Groovy and Grails Recipes', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Modern Java Web Development', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Java 7 Recipes', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Java EE 7 Recipes', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Beginning Java 7 ', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Pro Java 7 NIO.2', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Java 7 for Absolute Beginners', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (3, 'Oracle Certified Java Enterprise Architect Java EE7', 'Apress'),
insert into Book (CATEGORY_ID, BOOK_TITLE, PUBLISHER) values (4, 'Beginning Scala', 'Apress'),
You can verify the populated Book table as illustrated in Figure 1-17.
Figure 1-17. All books in the Book table
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (1, 'Luke', 'VanderHart'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (2, 'Vishal', 'Layka'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (3, 'Jeff', 'Brown'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (4, 'Bashar', 'Jawad'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (5, 'Vishal', 'Layka'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (6, 'Josh', 'Juneau'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (7, 'Josh', 'Juneau'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (8, 'Jeff', 'Friesen'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (9, 'Anghel', 'Leonard'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (10, 'Jay', 'Bryant'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (11, 'B V', 'Kumar'),
insert into Author (BOOK_ID, FIRST_NAME, LAST_NAME) values (12, 'David', 'Pollak'),
You can verify the populated Author table as illustrated in Figure 1-18.
Figure 1-18. All authors in the Author table
Data Access Layer for the Bookstore Application
Now that the database is ready, you will build the data access layer for application. The data access layer will retrieve the data via JDBC from the database and directly map the result set into Java objects. These Java objects are the domain objects in the application that are the Java representation of the tables in the database. The data access layer is responsible for interfacing with the underlying persistence mechanism in a transparent way in order to store and retrieve objects from the database. This transparency means that the data access layer can switch the persistence mechanism from plain JDBC14 to ORM15 persistence technologies such as Hibernate,16 JPA,17 and so on, without affecting the client of the data access layer. This transparency is achieved via the data access object (DAO) pattern, as illustrated in Figure 1-19. The DAO object provides an interface to the database or the underlying persistence mechanism, thus abstracting the underlying implementation from the client.
Figure 1-19. DAO pattern
The DAO maps application calls to the persistence mechanism and provides specific data operations without exposing details of the database. The DAO interface abstracts the implementation details of accessing the data from the client (application object) and provides the domain-specific objects that the client (application object) needs.
First you need to create the domain-specific classes for the Java object representations of the database tables Listings 1-4, 1-5, and 1-6 show the Book, Author, and Category domain classes, respectively.
Listing 1-4. Model: Category
package com.apress.books.model;
public class Category {
private Long id;
private String categoryDescription;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCategoryDescription() {
returncategoryDescription;
}
public void setCategoryDescription(String categoryDescription) {
this.categoryDescription = categoryDescription;
}
public String toString() {
return "Category - Id: " + id + ", Category Description: "
+ categoryDescription;
}
}
Listing 1-5. Model: Book
package com.apress.books.model;
import java.util.List;
import com.apress.books.model.Author;
public class Book {
private Long id;
private Long categoryId;
private String bookTitle;
private List<Author> authors;
private String publisherName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCategoryId() {
return categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
}
public String getBookTitle() {
return bookTitle;
}
public void setBookTitle(String bookTitle) {
this.bookTitle = bookTitle;
}
public List<Author> getAuthors() {
return authors;
}
public void setAuthors(List272103_1_En authors) {
this.authors = authors;
}
public String getPublisherName() {
return publisherName;
}
public void setPublisherName(String publisherName) {
this.publisherName = publisherName;
}
public String toString() {
return "Book - Id: " + id + ", Book Title: " + bookTitle;
}
}
Listing 1-6. Model: Author
package com.apress.books.model;
public class Author {
private Long id;
private Long bookId;
private String firstName;
private String lastName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getBookId() {
return bookId;
}
public void setBookId(Long bookId) {
this.bookId = bookId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String toString() {
return "Author - Id: " + id + ", Book id: " + bookId + ", First Name: "
+ firstName + ", Last Name: " +lastName;
}
}
Now let’s start with a simple interface for BookDAO that encapsulates all the data access by your web application. Listing 1-7 shows the BookDAO interface.
Listing 1-7. BookDAO Interface
1. package com.apress.books.dao;
2.
3. import java.util.List;
4.
5. import com.apress.books.model.Book;
6. import com.apress.books.model.Category;
7.
8. public interface BookDAO {
9. public List<Book>findAllBooks();
10.
11. public List<Book>searchBooksByKeyword(String keyWord);
12.
13. public List<Category>findAllCategories();
14.
15. public void insert(Book book);
16.
17. public void update(Book book);
18.
19. public void delete(Long bookId);
20.
21. }
The methods in this interface correspond to the CRUD terms (in other words, create, read, update, and delete) of the application. Listing 1-8 illustrates the implementation of the BookDAO interface.
Listing 1-8. Implementation of the BookDAO Interface
1. package com.apress.books.dao;
2.
3. import java.sql.Connection;
4. import java.sql.DriverManager;
5. import java.sql.PreparedStatement;
6. import java.sql.ResultSet;
7. import java.sql.SQLException;
8. import java.sql.Statement;
9. import java.util.ArrayList;
10. import java.util.List;
11.
12. import java.apress.books.model.Author;
13. import java.apress.books.model.Book;
14. import java.apress.books.model.Category;
15.
16. public class BookDAOImpl implements BookDAO {
17.
18. static {
19. try {
20. Class.forName("com.mysql.jdbc.Driver");
21. } catch (ClassNotFoundException ex) {
22. }
23. }
24.
25. private Connection getConnection() throws SQLException {
26. return DriverManager.getConnection("jdbc:mysql://localhost:3306/books",
27. "root", "password");
28. }
29.
30. private void closeConnection(Connection connection) {
31. if (connection == null)
32. return;
33. try {
34. connection.close();
35. } catch (SQLException ex) {
36. }
37. }
38.
39. public List<Book> findAllBooks() {
40. List<Book> result = new ArrayList<>();
41. List<Author> authorList = new ArrayList<>();
42.
43. String sql = "select * from book inner join author on book.id = author.book_id";
44.
45. Connection connection = null;
46. try {
47. connection = getConnection();
48. PreparedStatement statement = connection.prepareStatement(sql);
49. ResultSet resultSet = statement.executeQuery();
50. while (resultSet.next()) {
51. Book book = new Book();
52. Author author = new Author();
53. book.setId(resultSet.getLong("id"));
54. book.setBookTitle(resultSet.getString("book_title"));
55. book.setCategoryId(resultSet.getLong("category_id"));
56. author.setBookId(resultSet.getLong("book_Id"));
57. author.setFirstName(resultSet.getString("first_name"));
58. author.setLastName(resultSet.getString("last_name"));
59. authorList.add(author);
60. book.setAuthors(authorList);
61. book.setPublisherName(resultSet.getString("publisher"));
62. result.add(book);
63. }
64. } catch (SQLException ex) {
65. ex.printStackTrace();
66. } finally {
67. closeConnection(connection);
68. }
69. return result;
70. }
71.
72.
73. public List<Book> searchBooksByKeyword(String keyWord) {
74. List<Book> result = new ArrayList<>();
75. List<Author> authorList = new ArrayList<>();
76.
77. String sql = "select * from book inner join author on book.id = author.book_id"
78. + " where book_title like '%"
79. + keyWord.trim()
80. + "%'"
81. + " or first_name like '%"
82. + keyWord.trim()
83. + "%'"
84. + " or last_name like '%" + keyWord.trim() + "%'";
85.
86. Connection connection = null;
87. try {
88.
89. connection = getConnection();
90. PreparedStatement statement = connection.prepareStatement(sql);
91. ResultSet resultSet = statement.executeQuery();
92. while (resultSet.next()) {
93. Book book = new Book();
94. Author author = new Author();
95. book.setId(resultSet.getLong("id"));
96. book.setBookTitle(resultSet.getString("book_title"));
97. book.setPublisherName(resultSet.getString("publisher"));
98. author.setFirstName(resultSet.getString("first_name"));
99. author.setLastName(resultSet.getString("last_name"));
100. author.setBookId(resultSet.getLong("book_id"));
101. authorList.add(author);
102. book.setAuthors(authorList);
103. result.add(book);
104. }
105. } catch (SQLException ex) {
106. ex.printStackTrace();
107. } finally {
108. closeConnection(connection);
109. }
110.
111. return result;
112. }
113.
114. public List<Category> findAllCategories() {
115. List<Category> result = new ArrayList<>();
116. String sql = "select * from category";
117.
118. Connection connection = null;
119. try {
120. connection = getConnection();
121. PreparedStatement statement = connection.prepareStatement(sql);
122. ResultSet resultSet = statement.executeQuery();
123. while (resultSet.next()) {
124. Category category = new Category();
125. category.setId(resultSet.getLong("id"));
126. category.setCategoryDescription(resultSet
127. .getString("category_description"));
128. result.add(category);
129. }
130. } catch (SQLException ex) {
131. ex.printStackTrace();
132. } finally {
133. closeConnection(connection);
134. }
135. return result;
136. }
137.
138. public void insert(Book book) {
139. }
140.
141. public void update(Book book) {
142. }
143.
144. public void delete(Long bookId) {
145.
146. }
147. }
Listing 1-8 is an implementation of the BookDao interface for interacting with; this interaction includes connecting to the database and selecting, deleting, and updating data via pure JDBC. JDBC provides the driver that is specific to each database and that allows Java code the database.
Note You can download the MySQL Connector/J from http://dev.mysql.com/downloads/connector/j/. Place this connector JAR in the classpath of the project.
Client for the Data Access Layer
Now that your data access layer is ready, you will query it with a stand-alone Java application. In Chapter 2, you will replace this Java app with a web application. Listing 1-9 illustrates the Java application.
Listing 1-9. Stand-Alone Bookstore Java App
1. package com.apress.books.client;
2. import java.util.List;
3.
4. import com.apress.books.dao.BookDAO;
5. import com.apress.books.dao.BookDAOImpl;
6. import com.apress.books.model.Book;
7.
8. public class BookApp {
9. private static BookDAO bookDao = new BookDAOImpl();
10.
11. public static void main(String[] args) {
12. // List all books
13. System.err.println("Listing all Books:");
14. findAllBooks();
15. System.out.println();
16. // search book by keyword
17. System.err.println("Search book by keyword in book title : Groovy:");
18.
19. searchBooks("Groovy");
20. System.out.println();
21.
22. System.err.println("Search book by keyword in author's name : Josh:");
23.
24. searchBooks("Josh");
25.
26.
27. }
28.
29. private static void findAllBooks() {
30. List<Book> books = bookDao.findAllBooks();
31. for (Book book : books) {
32. System.out.println(book);
33. }
34. }
35. private static void searchBooks(String keyWord) {
36. List<Book> books = bookDao.searchBooksByKeyword(keyWord);
37. for (Book book : books) {
38. System.out.println(book);
39. }
40. }
41. }
Figure 1-20 illustrates the directory structure of the stand-alone application.
Figure 1-20. Directory structure of the stand-alone bookstore application
Running this application gives the following output:
In the next chapter, you will develop the web layer that will replace this client and that will call the data access layer in the bookstore web application.
Trends and Technologies in the Java Web Landscape
Now it is time to delve into the trends and technologies in today’s Java web landscape. This may seem daunting to a newcomer to Java, but the goal is to familiarize you with the tools, technologies, and trends in Java web application development in order to give you a glimpse of the modern Java landscape. When you learn to develop web applications using rapid web frameworks such as Grails 2 and Play 2, you will see that most of these tools and technologies are provided out of the box.
As mentioned throughout the chapter, the JVM, originally intended for Java, can now host a myriad of programming languages, including Groovy and Scala. As a consequence of this emerging multiprogramming paradigm, modern web applications are often characterized in one or more of the following ways:
One of the greatest strengths of the Web is that it is flexible. This flexibility, however, is also its greatest weakness. This weakness manifests itself when a web application tested on one browser is viewed on the different browser and doesn’t perform properly. This cross-browser compatibility problem has only grown with the advent of smartphones. As shown in Figure 1-21, as of the end of 2013, there are 6.8 billion mobile subscriptions worldwide, and that number is poised to grow to 8 billion by 2016 (www.itu.int/ITU-D/ict/facts/index.html).
Figure 1-21. Mobile subscriptions
Web applications are expected to run on smartphones as well as on the desktop, but creating separate web applications for the desktop and the smartphone has significant overhead for development as well as maintenance. In May 2010, Ethan Marcotte wrote an article for A List Apart titled “Responsive Web Design” (http://d.alistapart.com/responsive-web-design/ex/ex-site-flexible.html) that defined a groundbreaking approach. He used existing tools (which will be explained later in this section) to create a site that displays beautifully on different devices, as illustrated in Figure 1-22 and Figure 1-23.
Figure 1-22. Responsive web site by Ethan Marcotte
Figure 1-23. The same responsive site on a smartphone
Responsive web applications are device-agnostic, in that they adapt themselves to the device on which they are run. The technique goes as far as rethinking the way page layouts are designed. You can go one step further by designing the web application with the smallest screen (smartphones) in mind and then progressively enhance the application to run on desktop screens. This technique is known as mobile-first design. The philosophy of a mobile-first design is that if you design the interface and the web components to run with acceptable performance on a smartphone, the performance on desktop screens will be blazing fast. In addition, using the smartphone real estate wisely will also be applied to the desktop screens, which will result in better usability of the application.
The core technologies employed in developing responsive web applications are CSS3,18 jQuery19 and jQuery plug-ins,20 LESS,21 CoffeeScript,22 and front-end frameworks such as Bootstrap,23 Polyfills, and Modernizr.
Here are some important definitions in the responsive world:
Single-Page Web Application (SPA)
Another trend in web application development is a single-page web application (SPA).
SPAs are built using Node.js25 as the web server. AngularJS is a full-featured SPA framework.
Real-Time Web Application
A real-time web application delivers responses to events in a measurable and acceptable time period, depending on the nature of the event, by means of asynchronous, bidirectional communication between the client and the server. WebSocket is the core technology employed for developing real-time web applications. WebSocket provides a full-duplex and bidirectional communication protocol over a single TCP connection. That is, a client and a server can send messages to each other and independent of each other.
A few examples of the applications that require real-time functionality are chat applications, multiplayer online games, stock trading applications, and so on.
Note The Java API for WebSocket is defined as JSR 356; see Table 1-3.
Reactive applications are a new class of applications that are fundamentally different from traditional web-based applications and are driven by the Typesafe26 Reactive Platform. The Typesafe Reactive Platform is a suite of integrated products consisting of the Play 2 framework, Akka,27 and Scala, along with the Typesafe Console for command and control. Reactive programming is becoming crucial because of multicore processors and because it advocates asynchronous and event-based programming. The Play framework is an alternative to the enterprise Java stacks. Play is built for the needs of modern web and mobile applications, leveraging technologies such as REST, JSON, and WebSocket, to name a few. These technologies allow the creation of rich, highly interactive user interfaces rendered via any modern browser, while at the same time making it easier to render portions of the page in parallel and to do partial-page updates or progressive enhancements.
A mashup is a web application that uses content from more than one source to create a new service displayed in a single graphical interface. With mashups you can develop powerful applications by combining web services. You can find popular APIs for mashups at www.programmableweb.com/apis/directory/1?sort=mashups. This section will focus on web services and then touch on a fascinating trend, which is still an area of research: the Semantic Web.
A web service is a software component stored on one machine that can be accessed over the network by an application (or other software component) on another machine. The machine on which a web service resides is referred to as a web service host. The client application sends a request over a network to the web service host, which processes the request and returns the response. Making a web service available to receive client requests is known as publishing a web service; using a web service from a client application is known as consuming a web service.
Web services use technologies such as XML and JSON28 for data interchange.
JavaScript Object Notation
JavaScript Object Notation (JSON) is used for representing data as an alternative to XML. JSON reduces the payload of web requests, improving the overall performance of a web application. JSON is a text-based data-interchange format used to represent objects in JavaScript as collections of name-value pairs represented as Strings.
Note JSON Processing is defined as the Java API for JSON Processing in JSR 353; see Table 1-3.
Two Java APIs facilitate web services:
Simple Object Access Protocol
The Simple Object Access Protocol (SOAP) is a platform-independent protocol that uses XML to interact with web services, typically over HTTP. Each request and response is packaged in a SOAP message, which is XML markup containing the information that a web service requires to process the message. A SOAP web service works as follows:
Representational State Transfer
The term representational state transfer (REST) was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation30 at UC Irvine. REST refers to an architectural style for implementing web services called RESTful web services. Each method in a RESTful web service is identified by a unique URL.
Note RESTful web services are defined as JSR 339, as shown in Table 1-3.
Unlike SOAP, REST does the following:
Web 2.0 began to take shape in 2004. It was pioneered by Google and followed by social applications such as video sharing, social networking, microblogging, photo sharing, Wikipedia, and virtual worlds such as Second Life. Mashups played a major role in the evolution of social applications and Web 2.0.
The term Semantic Web refers to the W3C’s vision of the Web of linked data. The Semantic Web can be viewed as a set of standards that allow machines to understand the meaning of information on the Web. The Web as it is today constitutes data that has no meaning in itself, and the meaning has to be constituted manually after gathering the data from the Web. Semantic Web technologies enable you to create data stores on the Web, build vocabularies, and write rules for handling data. Linked data are empowered by technologies such as RDF,31 SPARQL,32 and OWL.33 The Semantic Web is the future of the Web and is a subject of ongoing research. I recommend Aaron Swartz’s A Programmable Web: An Unfinished Work34 as an excellent resource on the Semantic Web. You can also follow the latest news on the Semantic Web.
Summary
This chapter introduced the Java language and then took you on a whirlwind tour through the Java landscape. The diverse landscape of the Java world consists of several web frameworks (such as Struts 2, Spring Web MVC, JSF 2, Grails 2 and Play 2) that make development much easier; thus, as a Java web developer, you need to be familiar with these web frameworks. Modern Java is more than just a language; it is now a fully optimized platform for several other industry-strength languages such as Groovy, Clojure, and Scala. All these languages, especially Groovy, have a close association with Java, and you will come across web applications before long where Java and these alternative JVM languages will work in tandem.
The subsequent chapters will address all these needs of a modern Java web developer. Specifically, in the next chapter, you will create a Hello World web application that utilizes the basic building blocks of a web application, namely, servlets and Java Server Pages. From there, you will then transform the stand-alone application into your first full-blown web application: a bookstore application using servlets and JSP.
1http://cr.openjdk.java.net/∼jrose/pres/200910-VMIL.pdf
4www.oracle.com/technetwork/java/javaee/overview/index.html
9https://developer.mozilla.org/en-US/docs/Rhino_documentation
10www.oracle.com/technetwork/java/javaee/tech/index.html
11www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html
14www.oracle.com/technetwork/java/overview-141217.html
15http://en.wikipedia.org/wiki/Object-relational_mapping
17www.oracle.com/technetwork/java/javaee/tech/persistence-jsp-140049.html
18www.w3.org/Style/CSS/current-work.en.html
24www.w3.org/wiki/The_principles_of_unobtrusive_JavaScript
30www.ics.uci.edu/∼fielding/pubs/dissertation/rest_arch_style.htm
32www.w3.org/TR/rdf-sparql-query/
34www.morganclaypool.com/doi/pdf/10.2200/S00481ED1V01Y201302WBE005