Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Spring MVC Blueprints
Spring MVC Blueprints

Spring MVC Blueprints: Design and implement real-world web-based applications using the Spring Framework 4.x specification based on technical documentation

eBook
AU$53.99 AU$60.99
Paperback
AU$75.99
Subscription
Free Trial
Renews at AU$24.99p/m

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Spring MVC Blueprints

Chapter 1.  Creating a Personal Web Portal (PWP)

This chapter is all about creating a robust and simple personal web portal that can serve as a personal web page, or a professional reference site, for anyone. Usually, these kinds of websites are used as mashups, or dashboards, of centralized sources of information describing an individual or group.

Technically, a personal web portal is a composition of web components like CSS, HTML, and JavaScript, woven together to create a formal, simple or exquisite presentation of any content. It can be used, in its simplest form, as a personal portfolio or an enterprise form like an e-commerce content management system. Commercially, these portals are drafted and designed using the principles of the Rich-client platform or responsive web designs. In the industry, most companies suggest that clients try easy-to-use-tools like PHP frameworks (for example, CodeIgniterLaravelDrupal) and seldom advise using JEE-based portals.

Aside from the software processes and techniques that will be discussed in this chapter, the main goal is for the reader to have a quick but detailed review of the main recipe of Spring MVC 4.x implementation, and to know the importance of Java Enterprise Edition (JEE) concepts behind any Java Enterprise frameworks.

In this chapter, you will learn how to:

  • Implement a complete Spring MVC framework
  • Configure DispatcherServlet in a Spring MVC project
  • Learn types of controllers and their current features
  • Use controller annotations
  • Map URLs to controllers
  • Use different types of models in dispatching objects
  • Validate form domain objects using Validator
  • Convert and transform request parameter values into other object types
  • Configure views
  • Configure and implement e-mail transactions
  • Deploy Spring MVC projects

Overview of the project

The personal web portal (PWP) created publishes a simple biography, and professional information, one can at least share through the Web. The prototype is a session-driven one that can do dynamic transactions, like updating information on the web pages, and posting notes on the page without using any back-end database.

Through using wireframes, below are the initial drafts and design of the web portal:

  • The Home Page: This is the first page of the site that shows updatable quotes, and inspiring messages coming from the owner of the portal. It contains a sticky-note feature at the side that allows visitors to post their short greetings to the owner in real-time.
    Overview of the project
  • The Personal Information Page: This page highlights personal information of the owner including the owner's name, age, hobbies, birth date, and age. This page contains part of the blogger's educational history. The content is dynamic and can be updated at any time by the owner.
    Overview of the project
  • The Professional Information Page: This page presents details about the owner's career background. It lists down all the previous jobs of the account owner, and enumerates all skills-related information. This content is also updatable.
    Overview of the project
  • The Reach Out Page: This serves as the contact information page of the owner. Moreover, it allows visitors to send their contact information, and specifically their electronic mail address, to the portal owner.
    Overview of the project
  • Update pages: The HomePersonal and Professional pages have updateable pages for the owner to update the content of the portal. The prototype has the capability to update the information presented in the content at any time the user desires.

This simple prototype, called PWP, will give clear steps on how to build personal sites, from the ground up, using Spring MVC 4.x specifications. It will give enthusiasts the opportunity to start creating Spring-based web portals in just a day, without using any database backend. To those who are new to the Spring MVC 4.x concept, this chapter will be a good start in building full-blown portal sites.

Technical requirements

In order to start the development, the following tools need to be installed onto the platform:

  • Java Development Kit (JDK) 1.7.x
  • Spring Tool Suite (Eclipse) 3.6
  • Maven 3.x
  • Spring Framework 4.1
  • Apache Tomcat 7.x
  • Any operating system

First, the JDK 1.7.x installer must be installed. Visit the site http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html to download the installer.

Next, set up the Spring Tool Suite 3.6 (Eclipse-based) which will be the official Integrated Development Environment (IDE) of this book. Download the Spring Tool Suite 3.6 at https://spring.io/tools/sts.

Setting-up the development environment

This book recommends the Spring Tool Suite (Eclipse) 3.6 since it has all the Spring Framework 4.x plug-ins, and other dependencies needed by the projects. To start us off, the following image shows the dashboard of the STS IDE:

Setting-up the development environment

Conversely, Apache Maven 3.x will be used to build and deploy the project for this chapter. Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information (https://maven.apache.org/).

There is already a Maven plugin installed in the STS IDE that can be used to generate the needed development directory structure. Among the many ways to create Spring MVC projects, this chapter focuses on two styles, namely:

  • Converting a dynamic web project to a Maven specimen
  • Creating a Maven project from scratch

Converting a dynamic web project to a Maven project

To start creating the project, press CTRLN to browse the menu wizard of the IDE. This menu wizard contains all the types of project modules you'll need to start a project. The menu wizard should look similar to the following screenshot:

Converting a dynamic web project to a Maven project

Once on the menu, browse the Web option and choose Dynamic Web Project. Afterwards, just follow the series of instructions to create the chosen project module until you reached the last menu wizard, which looks like the following figure:

Converting a dynamic web project to a Maven project

This last instruction (Web Module panel) will auto-generate the deployment descriptor (web.xml) of the project. Always click on the Generate web-xml deployment descriptor checkbox option. The deployment descriptor is an XML file that must reside inside the /WEB-INF/ folder of all JEE projects. This file describes how a component, module or application can be deployed. A JEE project must always be in the web.xml file otherwise the project will be defective.

Note

Since the Spring 4.x container supports the Servlet Specification 3.0 in Tomcat 7 and above, web.xml is no longer mandatory and can be replaced by org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer or  org.springframework.web.servlet.support.AbstractDispatcherServletInitializer class.

The next major step is to convert the newly created dynamic web project to a Maven one. To complete the conversion, right-click on the project and navigate to the ConfigureConvert Maven Project command set, as shown in the following image:

Converting a dynamic web project to a Maven project

It is always best for the developer to study the directory structure of the project folder created before the actual implementation starts. The following is the directory structure of the Maven project after the conversion:

Converting a dynamic web project to a Maven project

The project directories are just like the usual Eclipse dynamic web project without the pom.xml file.

Creating a Maven project from scratch

Another method of creating a Spring MVC web project is by creating a Maven project from the start. Be sure to install the Maven 3.2 plugin in STS Eclipse. Browse the menu wizard again, and locate the Maven option. Click on the Maven Project to generate a new Maven project.

Creating a Maven project from scratch

After clicking this option, a wizard will pop up, asking if an archetype is needed or not to create the Maven project. An archetype is a Maven plugin whose main objective is to create a project structure as per its template. To start quickly, choose an archetype plugin to create a simple Java application here. It is recommended to create the project using the archetype maven-archetype-webapp. However, skipping the archetype selection can still be a valid option.

Creating a Maven project from scratch

After you've done this, proceed with the Select an Archetype window shown in the following screenshot. Locate maven-archetype-webapp then proceed with the last process.

Creating a Maven project from scratch

The selection of the Archetype maven-archetype-webapp will require the input of Maven parameters before ending the whole process with a new Maven project:

Creating a Maven project from scratch

The required parameters for the Maven group or project are as follows:

  • Group ID (groupId): This is the ID of the project's group and must be unique among all the project's groups.
  • Artifact ID (artifactId): This is the ID of the project. This is generally the name of the project.
  • Version (version): This is the version of the project.
  • Package (package): The initial or core package of the sources.

For more information on Maven plugin and configuration details, visit the documentation and samples on the site http://maven.apache.org/.

After providing the Maven parameters, the project source folder structure will be similar to the following screenshot:

Creating a Maven project from scratch

The pom.xml file

The basic fundamental unit of work in Maven is the pom.xml file. This XML file is the main part of the Maven project folder structure, and is always located in the base directory of the project. The file contains all the necessary archetype plugins and dependencies for project building and deployment.

The PWP has this pom.xml file that builds sources, creates project WAR files, and deploys the projects with web.xml to the Tomcat server.

<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/xsd/maven-4.0.0.xsd"> 
  <modelVersion>4.0.0</modelVersion> 
  <groupId>org.packt.spring.codes</groupId> 
  <artifactId>ChapterOne</artifactId> 
  <version>0.0.1-SNAPSHOT</version> 
  <packaging>war</packaging> 
  <name>ChapterOne</name> 
  <description>Personal Web Portal</description> 
 
  <!-- properties --> 
  <properties> 
    <spring.version>4.1.2.RELEASE</spring.version> 
    <servlet.api.version>3.1.0</servlet.api.version> 
  </properties> 
  <!-- dependencies --> 
 
  <dependencies> 
    <dependency> 
    <groupId>javax.mail</groupId> 
    <artifactId>mail</artifactId> 
    <version>1.4.3</version> 
  </dependency> 
 
  <dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-core</artifactId> 
    <version>${spring.version}</version> 
  </dependency> 
 
  <dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-beans</artifactId> 
    <version>${spring.version}</version> 
  </dependency> 
 
  <!-- Rest of the dependencies in sources --> 
  </dependencies> 
 
  <build> 
    <finalName>spring-mvc-maven-webapp-from-scratch</finalName> 
      <plugins> 
        <!-- Apache Tomcat 7 Maven Plugin --> 
        <-- 
        <plugin> 
          <groupId>org.apache.tomcat.maven</groupId> 
          <artifactId>tomcat7-maven-plugin</artifactId> 
          <version>2.2</version> 
          <configuration> 
 
            <url>http://localhost:8080/manager/text</url> 
            <path>/ch01</path> 
            <username>admin</username> 
            <password>admin</password> 
          </configuration> 
        </plugin> 
        --> 
        <plugin> 
          <groupId>org.apache.maven.plugins</groupId> 
          <artifactId>maven-compiler-plugin</artifactId> 
          <version>3.1</version> 
          <configuration> 
            <source>1.7</source> 
            <target>1.7</target> 
          </configuration> 
        </plugin> 
        <!-- Mojo Maven Plugin --> 
          <plugin> 
            <groupId>org.codehaus.mojo</groupId> 
            <artifactId>tomcat-maven-plugin</artifactId> 
            <version>1.1</version> 
            <configuration> 
              <url>http://localhost:8080/manager/text</url> 
              <server>TomcatServer</server> 
              <path>/ch01</path> 
            </configuration> 
          </plugin> 
        </plugins> 
    </build> 
  </project> 

After setting the development and deployment environment, it is time to start configuring out the Spring MVC component of PWP.

Project deployment

Apache Tomcat 7 will be used as the application server for this chapter. There are two popular Maven plugins that can be used to deploy applications to Tomcat: the Apache Maven plugin and the Mojo Maven plugin. By default, this book uses the Mojo Maven plugin.

To deploy a Maven project to Tomcat using the Mojo Maven plugin, the following configuration must be followed:

  1. Locate the user/conf/tomcat-users.xml file on the Tomcat server and add the desired user with administrator rights. Information like role, username and password of the added user must be added inside the <tomcat-user> tag. A sample configuration is shown in the following code snippet:
          <role rolename="manager"/> 
          <role rolename="admin"/> 
          <user username="admin" password="admin" 
          roles="admin,manager "/> 
    
    • Now save the file.
  2. Locate the file ~/.m2/settings.xml in Maven. If the file is non-existent, download Maven from its site and copy the settings.xml to ~/.m2. Open the file and locate the <servers> tag. Insert the following tag inside the <servers> tag.
            <server> 
              <id>TomcatServer</id> 
              <username>admin</username> 
              <password>admin</password> 
            </server> 
    
    • The <id> is any desired name for the Tomcat server that will be later called by the pom.xml plugin for Tomcat 7. The <username> and <password> are the server credentials manually added in /conf/tomcat-users.xml above. Save the file.
  3. Open pom.xml and add the following Maven plugin for Tomcat 7 server.
            <plugin> 
              <groupId>org.codehaus.mojo</groupId> 
              <artifactId>tomcat-maven-plugin</artifactId> 
              <version>1.1</version> 
              <configuration> 
                <url>http://localhost:8080/manager/text</url> 
                <server>TomcatServer</server> 
                <path>/ch01</path> 
              </configuration> 
            </plugin> 
    

The <configuration> settings contain information of where to deploy the project (<url>), what context root to use (<path>/), and the server name (<server>) used in the settings.xml file.

To deploy using the Apache Tomcat7 Maven plugin, the <configuration> tag only needs the <username> and <password> tags of the administration console, including the <url> and the <path>.

Maven deployment process

All projects are deployed in the Tomcat 7 server using the Maven plugin installed in STS. Follow the steps below to properly deploy the Spring MVC projects.

  1. Be sure to have a correctly configured Maven project with the appropriate POM configuration shown in the preceding figure.
  2. Right-click on the project and locate Run As in the menu options. Then, locate Maven build... in the sub-menu option, to configure the Maven goals for the first time. Maven goal is a task or command that is executed to build and manage Maven projects.
    Maven deployment process
  3. After this, a Maven configuration panel will pop up to write the needed goals for deployment, and to launch the deployment process. If the Mojo Maven plugin is used, write on the Goals textbox the following: clean install tomcat:deploy. If the Apache Tomcat7 Maven plugin is used, the goals must be: clean install tomcat7:deploy. Aside from these goals, there are some that can be essential for management like remove, update and re-deploy.
    Maven deployment process
  4. Click the Run button to launch the deployment. All the Maven execution logs will be shown on the console. The outcome of the deployment will be either a BUILD SUCCESS or a BUILD FAILURE.

Project libraries and dependencies

Configure pom.xml to add the major Spring Framework 4.x libraries (JAR files) for the PWP project. These dependency modules are the following:

  • spring-core (Spring core module): This contains the core components of the framework which includes the Inverse of Control principle and Dependency Injection (DI).
  • spring-beans (Spring bean module): This contains the bean generation using BeanFactory and fetches injected beans using the method getBean().
  • spring-context (Spring context module): Built by the core and bean modules that provide the interfaces of ApplicationContext with some features like resource bundling, internationalization, and scheduling.
  • spring-context-support (Spring context support module): This module contains the classes needed for integrating third-party applications to a Spring Application Context.
  • spring-web: This contains the web features of the Spring Framework which includes the initialization of the IoC container using servlet listeners and a web-oriented application context.
  • spring-webmvc (Spring MVC module): This is the module that has the MVC implementations and features.
  • spring-tx (Spring Transaction module): This contains transaction management on Bean object declarations with some special interfaces for all the POJO objects.

Aside from the other non-framework libraries, the following are auxiliary JAR files that support the Spring Framework 4.x core libraries:

  • servlet-api: This contains all the classes and interfaces that describe the interaction between a servlet class and the runtime environment provided for the instance of a class within the bound of the servlet container.
  • jsp-api: This contains all the classes that implement the JspPage interface.
  • jstl: This contains all the classes and interfaces for Taglib support for all JSP pages.
  • javax-mail: This provides a platform-independent and protocol-independent framework to build mail and messaging applications.
  • javax.validation: This provides JSR-303 annotations for Java Bean validation.

All of these dependencies must be added to the pom.xml of the Maven project.

Overview of the Spring MVC specification

The Spring MVC framework derives its specification from the Model-View-Controller (MVC) design pattern that separates the application into layers such as business, logic, navigation and presentation. The principle behind this design pattern is to create a de-coupled or loosely-coupled architecture, which is more flexible than the tightly-coupled frameworks.

Technically, Spring MVC works starts with a DispatcherServlet that dispatches requests to handlers, with configurable handler mappings, view resolution, locale, time zone and theme resolution, as well as support for uploading files. The default handler is based on the @Controller and @RequestMapping annotations, offering a wide range of flexible handling methods. With the introduction of Spring 3.0, the @Controller mechanism also allows you to create RESTful Web sites and applications, through the @PathVariable annotation and other features (http://docs.spring.io/).

The following diagram depicts how DispatcherServlet manages the whole MVC framework while, at the same time, avoiding the Fat Controller syndrome.

Overview of the Spring MVC specification

The org.springframework.web.servlet.DispatcherServlet is an actual servlet in the web.xml file of your web application, declared using the standard servlet tags. Just like any typical servlets, it recognizes request transactions through URL mappings. This servlet serves as the front controller of the whole MVC project.

Since this PWP project is written using the Spring Framework 4.x specification, the implementations always starts by declaring the DispatcherServlet.

The project development

All the nuts and bolts involved in developing the PWP from scratch will be discussed in this topic. Each of the four web pages, including their internal processes, will be scrutinized using the codes of the project. The Spring MVC concepts will focus on the following areas:

  • Configuration of DispatcherServlet
  • Configuration of Spring container
  • Creating controllers
  • Types of attributes
  • Validation
  • Type conversion and transformation
  • E-mail support configuration
  • Views and ViewResolvers

Configuring the DispatcherServlet

We start creating the Spring MVC project by configuring the DispatcherServlet API class. The Spring MVC framework has the DispatcherServlet at the center of all request and response transactions as illustrated in the preceding figure.

From the point of view of the PWP, the DispatcherServlet starts receiving requests when the user starts running pages on the web browser. The processes are enumerated as follows:

  • When the container receives a request from a path, the DispatcherServlet checks whose controller is mapped to the path name.
  • Then, the controller acknowledges the request with the appropriate service methods (for example, GET, POST, PUT, HEAD), executes the appropriate transaction method with the given model(s), and then returns the view name to the DispatcherServlet.
  • Then, the DispatcherServlet checks which type of view resolver has been configured from its container. Through the view resolver, the DispatcherServlet will know the appropriate view that matches the given request.
  • Finally, the DispatcherServlet will process the transport of model data to the view for presentation or rendition.

The PWP has the following configuration for the DispatcherServlet:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://java.sun.com/xml/ns/javaee"  
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    id="WebApp_ID"  
  version="3.0"> 
  <display-name>ChapterOne</display-name> 
 
  <!-- Declare Spring DispatcherServlet --> 
  <servlet> 
    <servlet-name>pwp</servlet-name> 
    <servlet-class> 
      org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
  </servlet> 
  <servlet-mapping> 
    <servlet-name>pwp</servlet-name> 
    <url-pattern>*.html</url-pattern> 
  </servlet-mapping> 
 
  <!-- Spring accepted extension declared here below --> 
  <mime-mapping> 
    <extension>png</extension> 
    <mime-type>image/png</mime-type> 
  </mime-mapping> 
 
</web-app> 

Just like any typical JEE servlet, the tags <servlet> and <servlet-mapping> are used to declare the dispatcher servlet DispatcherServlet:

<servlet> 
  <servlet-name>pwp</servlet-name> 
  <servlet-class> 
    org.springframework.web.servlet.DispatcherServlet 
  </servlet-class> 
</servlet> 
<servlet-mapping> 
  <servlet-name>pwp</servlet-name> 
  <url-pattern>*.html</url-pattern> 
</servlet-mapping> 

The <servlet-name> tag does not only stand for the name of the servlet, but is also related to the name of a Spring container which will be tackled later. The  <url-pattern> indicates which type of valid URLs will be recognized by the DispatcherServlet during request-response transactions. In our preceding configuration, it shows that all URL must have an extension .html in order for the requests to be processed by the servlet.

When it comes to file types, the DispatcherServlet only considers content types declared with the <mime-mapping> tag. In this project, we only have PNG files needed by the portal.

  <mime-mapping> 
    <extension>png</extension> 
    <mime-type>image/png</mime-type> 
  </mime-mapping> 

Creating the Spring container

After we've configured the DispatcherServlet, the Spring MVC container must be created. The interface org.springframework.context.ApplicationContext is Spring's more advanced container. The implementation of this object manages other objects of the portal application that will be known later as beans. All beans are injected into this container so that the portal will just "fetch" them once they are needed in several transactions.

There are two ways to create a Spring MVC container and these are:

  • XML-based configuration
  • JavaConfig-based configuration

Spring container configuration using XML

Using our STS IDE, the ApplicationContext (applicationContext.xml) can be created using the Spring Eclipse plugin. Following is the menu wizard showing the plugin for the Spring Framework module:

Spring container configuration using XML

On the wizard, click on the Spring Bean Configuration File option which will guide you to the next instruction panel. This is the selection of the XSD namespaces needed by the applicationContext.xml for the Spring components.

Spring container configuration using XML

After choosing the necessary XSD namespaces needed for bean injections and configurations, the PWP's XML-based container will look like the following configuration:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:context="http://www.springframework.org/schema/context" 
  xmlns:oxm="http://www.springframework.org/schema/oxm"
  xmlns:tx="http://www.springframework.org/schema/tx" 
  xmlns:mvc="http://www.springframework.org/schema/mvc" 
  xsi:schemaLocation="http://www.springframework.org/schema/aop    http://www.springframework.org/schema/aop/spring-aop-4.1.xsd 
http://www.springframework.org/schema/oxm      http://www.springframework.org/schema/oxm/spring-oxm-4.1.xsd 
http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 
http://www.springframework.org/schema/context      http://www.springframework.org/schema/context/spring-context-4.1.xsd 
http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> 
 
    // all beans injected here 
</beans> 

The applicationContext.xml is loaded, accessed, and read by the DispatcherServlet. The convention used so the DispatcherServlet recognizes the container is to name our applicationContext.xml file using the format dispatcherServletName-servlet.xml, wherein the dispatcherServletName is the name indicated by the <servlet-name> tag:

<servlet> 
  <servlet-name>pwp</servlet-name> 
  <servlet-class> 
    org.springframework.web.servlet.DispatcherServlet 
  </servlet-class> 
</servlet> 

Thus, the PWP's applicationContext.xml file is named pwp-servlet.xml. The default filename of an XML-based Spring container must always follow the convention [dispatcher-servlet-name]-servlet.xml.

Spring container configuration using JavaConfig

The other type of implementation of the Spring MVC container is through the JavaConfig classes. In the JavaConfig method, every component tag has its respective annotation equivalent. Following is the equivalent configuration of the preceding XML-based setup.

package org.packt.personal.web.portal.config; 
import org.springframework.context.annotation.Configuration; 
 
@Configuration 
public class PersonalWebPortalConfig {   } 

The @Configuration annotation indicates that this class contains one or more bean methods (usually getters) annotated with @Bean that returns manageable beans of the container. Some references call this class a configurator class.

The two implementations are incomparable, but some projects mix them. XML-based Spring MVC containers become cumbersome when the files get larger, while annotation-based ones can be managed since they are just POJO-based. JavaConfig is a better approach when it comes to using a rapid application development (RAD) strategy. The reason for this is that when the number of components in the project increases, JavaConfig can only just manage the dependencies among beans through autowiring, which the XML cannot impose since the codes are decoupled from the dependency injection process. Debugging is also easy, since bug detection will be done during compilation, unlike in the XML-style where errors will be detected right after the deployment or execution of the application.

On the issue of mixing them, the project must choose which configuration is going to be bootstrapped by the container. If it is the JavaConfig, it must use the @ImportResource to load all the injected beans from the XML:

@Configuration 
@ImportResource("classpath:pws-servlet.xml") 
public class PersonalWebPortalConfig {   } 

If the XML-based configuration is used instead, the XML must use <context:component-scan="org.packt.personal.web.portal"/> to locate the @Configuration class and load all @Bean autowired in it.

In general, the XML-based method is preferred, whenever an Enterprise application is being developed, because XML is still widely used in systems integration techniques. Some legacy systems also preferred the XML-based container.

The PWP project has an XML-based and JavaConfig-based container.

Configuring the Spring container

Before we create controllers for our PWP project, the Spring container must be ready for bean injections and component declarations. First, our Spring MVC container must be annotation-driven so that we can utilize the annotation stereotypes used by the current Spring Framework specification in configuring containers.

To enable the use of annotations inside classes, the following tag must be appearing in the pwp-servlet.xml:

    <mvc:annotation-driven /> 

Second, when the <annotation-driven> tag is enabled, the container must automatically scan all component classes that are part of the Spring MVC web project. This will be enabled through inserting the following tag into the pwp-servlet.xml.

    <context:component-scan  
      base-package="org.packt.personal.web.portal" /> 

The base-package attribute indicates the base folder of the development directory structure (src) where all components and beans are located. Declaring this tag enables auto-detection of the bean components in the project, which includes the controllers.

Drop all static resources like the CSS files into the ch01/webapp folder. Declare the default servlet handler in order to allow the access of those static resources from the root of the web application even though the DispatcherServlet is registered at the context root ch01.

    <mvc:default-servlet-handler /> 

Then, use the <mvc:resources> element to point to the location of the static resources with a specific public URL pattern.

    <mvc:resources mapping="/css/**" location="/css/" /> 

The complete XML-based Spring container of PWP is shown as follows:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:context="http://www.springframework.org/schema/context" 
  xmlns:oxm="http://www.springframework.org/schema/oxm" 
  xmlns:tx="http://www.springframework.org/schema/tx" 
  xmlns:mvc="http://www.springframework.org/schema/mvc" 
  xsi:schemaLocation="http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.1.xsd 
    http://www.springframework.org/schema/oxm
    http://www.springframework.org/schema/oxm/spring-oxm-4.1.xsd 
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/
         spring-beans-4.1.xsd 
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/
         spring-context-4.1.xsd 
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> 
 
  <mvc:annotation-driven /> 
  <mvc:default-servlet-handler /> 
  <mvc:resources mapping="/css/**" location="/css/" /> 
</beans> 

The JavaConfig equivalent of our XML-based container will have this equivalent code:

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
// Rest of the imports in sources 
 
@Configuration 
@ComponentScan(basePackages="org.packt.personal.web.portal") 
@EnableWebMvc 
public class PWPConfiguration extends WebMvcConfigurerAdapter { 
 
  @Override 
    public void addResourceHandlers(ResourceHandlerRegistry      registry) { 
      registry.addResourceHandler("/css/**").       addResourceLocations("/css/"); 
    } 
} 

The @EnableWebMvc annotation is equivalent to <mvc:annotation-driven /> in the XML-based version . Lastly, the @ComponentScan annotation is equivalent to the <context:component-scan base-package=" org.packt.personal.web.portal "/> we have in our pwp-servlet.xml. To allow recognition to static resources, the application must override the resource handler method.

Creating the controllers

The PWP project will consist of four content pages each having its own use request transaction. Users can update three of the four contents using session handling. In order to implement services to each page, controller class must be created with the stereotype @Controller instead of extending controller base classes or Spring-specific APIs. The home page of PWP has the following controller declaration:

@Controller 
public class IndexController {  } 

Each controller class has more than service or handler methods. Each service method is being mapped to the user's request by the DispatcherServlet. A valid service or handler method must have a @RequestMapping stereotype written on top of the method or function signature. A sample controller with a service method is shown as follows:

@Controller 
public class IndexController { 
 
  @RequestMapping(value="/index", method=RequestMethod.GET) 
  public String getIndex(Model model) { 
    model.addAttribute("greetings",  "Welcome Page"); 
    return "index"; 
  } 
} 

A service method is mapped to at least one URL or path, and has an HTTP method declared. The preceding sample getIndex() is mapped to the /index.html and processes a GET request transaction.

There are actually four general classifications of a controller and these are the following:

  • A controller that calls a page only: These controllers simply provide services that call view names like the following sample:
        @Controller 
          public class IndexController { 
 
            @RequestMapping(value="/index", 
            method=RequestMethod.GET) 
            public String getIndex() { 
              return "index"; 
            } 
          } 
  • A controller that brings model(s) to views: This group of controllers transport models to the view for presentation purposes. A controller can pass an org.springframework.web.ModelAndView to successful view pages with an object containing all the necessary objects, like in the following snippet:
        @Controller 
          public class IndexController { 
 
            @RequestMapping(value="/index", 
            method=RequestMethod.GET) 
            public ModelAndView getIndex() { 
              Map<String, Object> model = new HashMap<>(); 
              model.put("greetings",  "Welcome Page"); 
              return new ModelAndView("index", "model", model); 
            } 
 
          } 
  • On the other hand, the most modern and simple way of transporting model data is through the use of the org.springframework.ui.Model object, wherein all objects transported to the views are either @ModelAttribute or @SessionAttribute. A simple sample on this approach is given as follows:
        @Controller 
          public class IndexController { 
 
            @RequestMapping(value="/index", 
            method=RequestMethod.GET) 
            public String getIndex(Model model) { 
              model.addAttribute("greetings",  "Welcome Page"); 
              return "index"; 
            } 
          } 
  • A controller that has multi-services or multi-actions: Controllers that have more than one service or action:
        @Controller 
        public class IndexController { 
 
          @RequestMapping(value="/index", 
          method=RequestMethod.GET) 
          public String getIndex(Model model){ 
            model.addAttribute("greetings",  "Welcome Page"); 
            return "index"; 
          } 
 
          @RequestMapping(value="/index_post", 
            method=RequestMethod.POST) 
            public String postIndex(Model model) { 
              model.addAttribute("greetings",  "Welcome Page"); 
              return "index"; 
            } 
        } 
  • A controller that accepts request parameters (form controllers): These controllers have a form view and a success view. The form view accepts request parameters from the client. Then the request will be mapped to the service method, which will process all the request data. The result will be transported as a model, or as an attribute, to the corresponding view. Following is a sample snippet:
         @Controller 
         @SessionAttributes(value={"statusSess", "homeSess"}) 
         @RequestMapping("/pwp/index_update") 
         public class IndexUpdateController { 
 
         @Autowired 
         private Validator indexValidator; 
 
         @InitBinder("homeForm") 
         public void initBinder(WebDataBinder binder) { 
         binder.setValidator(indexValidator); 
         } 
 
         @RequestMapping(method=RequestMethod.GET) 
 
         public String initForm(Model model) { 
         Home homeForm = new Home(); 
         model.addAttribute("homeForm", homeForm); 
         return "index_update"; 
         } 
 
         @RequestMapping(method=RequestMethod.POST) 
         public String submitForm(Model model, 
         @ModelAttribute("homeForm") 
         @Validated Home homeForm, BindingResult binding) { 
         model.addAttribute("homeForm", homeForm); 
         String returnVal = "index"; 
         if(binding.hasErrors()) { 
         returnVal = "index_update"; 
         } else { 
         model.addAttribute("homeSess", homeForm); 
         model.addAttribute("statusSess", "undefault"); 
         } 
         return returnVal; 
         } 
         }

The PWP controllers

This project utilizes all the preceding controller classification except for multi-action controllers. Following is the finished product of the PWP that highlights the home page. All content pages have an equivalent update transaction for updating their content. The home page, in particular, is invoked through the URL http://localhost:8080/ch01/pwp/index.html where ch01 is the context root. With this URL, DispatcherServlet will look for the controller that has the service method bearing the path /pwp/index. Once the match is found, the service method calls the appropriate view with the data model, if there is one. The final step will be loading the content desired by the user.

The PWP controllers

A complete home page controller class with the default values of the cone is shown as follows:

package org.packt.personal.web.portal.controller; 
 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
 
import org.packt.personal.web.portal.model.form.Home; 
import org.packt.personal.web.portal.model.form.PostMessage; 
// Rest of the code in the sources 
 
@Controller 
@SessionAttributes("posts") 
@RequestMapping("pwp") 
public class IndexController { 
 
  @ModelAttribute("posts") 
  public List<PostMessage> newPosts() { 
    return initPost(); 
  } 
 
  @RequestMapping(value="/index", method=RequestMethod.GET) 
  public String getIndex(Model model,  @ModelAttribute("posts") 
    List<PostMessage> posts, 
    @ModelAttribute("postForm") PostMessage postForm) { 
 
      Home home = new Home(); 
      home.setMessage(initMessage()); 
      home.setQuote(initQuote()); 
      model.addAttribute("home",  home); 
        if(posts == null) posts = newPosts(); 
        if(validatePost(postForm)) { 
          postForm.setDatePosted(new Date()); 
          posts.add(postForm); 
        } 
        model.addAttribute("posts",  posts); 
      return "index"; 
  } 
 
  @RequestMapping(value="/index_redirect", 
    method=RequestMethod.GET) 
  public RedirectView updateIndex() { 
    return new RedirectView("/ch01/pwp/index_update.html"); 
  } 
 
  public String initQuote() { 
    String message = "Twenty years from now you will be more 
      disappointed by the things .......... -Mark Twain"; 
    return message; 
  } 
 
  public String initMessage() { 
    String message = "Having a positive outlook on life is a      crucial part of finding inspiration. In the paragraph above,      ......"; 
    return message; 
  } 
 
  public List<PostMessage> initPost() { 
    List<PostMessage> posts = new ArrayList<>(); 
    PostMessage post = new PostMessage(); 
    post.setSubject("Welcome!"); 
    post.setDatePosted(new Date()); 
    post.setPostedMsg("Hello visitors!Feelfree to post on my 
    portal!"); 
 
    posts.add(post); 
    return posts; 
  } 
 
  public boolean validatePost(PostMessage post) { 
    try { 
      if(post.getSubject().trim().length() == 0 || 
      post.getPostedMsg().trim().length() == 0) { 
        return false; 
      } 
    } 
    catch(Exception e) { 
      return false; 
    } 
    return true; 
  } 
} 

The method getIndex() is responsible for loading the home page initially. The default content for message and content are given by two methods, namely initMessage() and initPost(). The initPost() method initially populates the right navigation panel of the home page where all the posts will be listed. This posting feature will be elaborated on further in the next topics.

Generally, all these default methods are essential to generate the home page when no session data are available to replace this default content.

The update page on the home page will be invoked by clicking the Update button. Each portal has an Update button except for the Reach Out page. After clicking the Update button on the home page, DispatcherServlet will look for the service that has the URL path /pwp/index_redirect. There are two general ways to implement redirection and these are the following:

  • Using the RedirectView API: This process of redirection is done through implementation of the handler method that returns org.springframework.web.servlet.view.RedirectView. Following are some snippets that show how to implement redirection.
        @RequestMapping(value="/index_redirect",
                        method=RequestMethod.GET) 
          public RedirectView updateIndex() { 
            return new RedirectView("/ch01/pwp/index_update.html"); 
          } 
 
          @RequestMapping(value="/index_redirect",
                          method=RequestMethod.GET) 
            public String updateIndex() { 
              return (redirect:"/ch01/pwp/index_update.html"); 
            } 
  • Using the <c:url> JSTL tag: This process is a direct process of redirection and being configured on the view page.
            <c:url var=indexUpdate" value="/pwp/index_update.html"/> 
            <a href="<c:out value="${indexUpdate }"/>">Update Home</a>  
    
    The PWP controllers

After redirection to the update page, the home page has two important pieces of content information that need to be updated, and these are the message and quote portions of the page:

The PWP controllers

All update pages have validators to check the attributes of the form data. On the home page, users cannot input quotes or messages that are less than 50 and more than 500 alphanumeric characters. Validation and object type checking occurs only if our controllers have form views. A controller that has form and success views is implemented in a different way. Following is a template of a form controller that is used by the PWP project:

package org.packt.personal.web.portal.controller; 
 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
 
import org.packt.personal.web.portal.converter.AgeConverter; 
import org.packt.personal.web.portal.converter.BirthDateConverter; 
// Rest of the codes in the sources 
@Controller 
@SessionAttributes(value = {"pStatusSess", "personSess"}) 
@RequestMapping("/pwp/personal_update") 
public class PersonalUpdateController { 
 
  @Autowired 
  Validator personalValidator; 
 
  @InitBinder("personForm") 
  public void initBinder(WebDataBinder binder) { 
    binder.setValidator(personalValidator); 
    binder.registerCustomEditor(Integer.class, "biography.age", 
    new AgeConverter()); 
    binder.registerCustomEditor(Integer.class, "education.year", 
    new YearConverter()); 
    binder.registerCustomEditor(Date.class, "biography.birthDate", 
    new BirthDateConverter()); 
  } 
 
  @RequestMapping(method=RequestMethod.GET) 
  public String initForm(Model model) { 
    Biography bio = new Biography(); 
    Education educ = new Education(); 
    Personal personForm = new Personal(); 
    personForm.setBiography(bio); 
    personForm.setEducation(educ); 
    references(model); 
    model.addAttribute("personForm", personForm); 
    return "personal_update"; 
  } 
 
  @RequestMapping(method=RequestMethod.POST) 
  public String submitForm(Model model, 
  @ModelAttribute("personForm") @Validated Personal personForm, 
  BindingResult binding) { 
    model.addAttribute("personForm", personForm); 
    String returnVal = "personal"; 
    if(binding.hasErrors()) { 
      references(model); 
      returnVal = "personal_update"; 
    } else { 
      model.addAttribute("personSess", personForm); 
      model.addAttribute("pStatusSess", "undefault"); 
    } 
    return returnVal; 
 
  } 
 
  public void references(Model model) { 
    List<String> hobbiesList = new ArrayList<String>(); 
    hobbiesList.add("Not Applicable"); 
    hobbiesList.add("Singing"); 
    hobbiesList.add("Painting"); 
    hobbiesList.add("Traveling"); 
    hobbiesList.add("Writing"); 
    hobbiesList.add("Swimming"); 
    model.addAttribute("hobbiesList", hobbiesList); 
    // Rest of the code in sources 
  } 
} 

Although there is no restriction as to what, and how many, handler methods are needed in a typical controller class, a form controller has to maintain having only one @RequestMapping stereotype declared at the class level. The path indicated must be the controller's form view.

The preceding controller has two service operations namely the initForm() and submitForm() methods. The initForm() service is always a GET method, which always initializes the form view. It also binds the form domain object that contains the request data from the user. The submitForm() is a POST service that is executed after form submission. This automatically extracts the validated domain object from the form and transports any model to the result views.

The references() method is used to populate the form components found in the form view. Java Collection Framework (JCF) is used to contain all the data which can be hardcoded or which is from a data store.

The usual exception during form-handling happens when the form-backing object, or the model, is not set to bind with the form view. Whenever the browser calls the initForm(), the following exception will be encountered.

java.lang.IllegalStateException: 
  Neither BindingResult nor plain target object 
    for bean name 'home' available as request attribute 
      at o.s.w.s.s.BindStatus.<init>(BindStatus.java:141) 

In order for submitForm() to access the form-backing object, the @ModelAttribute annotation is needed to be declared in its parameters. An @ModelAttribute local parameter indicates that the argument will be retrieved from the form view. If not present in the form view, the argument must be instantiated first in the initForm(), and bound to the form view. Moreover, Spring MVC throws an exception when errors occur during request binding, by default. That is why in submitForm(), one of the arguments is for BindIngResult where we can extract all errors during the request transaction. The BindingResult argument needs to be positioned right after our form-backing object, which is a rare case when it comes to the @RequestMapping order of arguments.

If this rule is violated, the following exception will be thrown:

java.lang.IllegalStateException:
Errors/BindingResult argument declared without preceding model    attribute 

Using @ModelAttribute and @SessionAttributes

The Personal Web Portal (PWP) application does not have database connectivity since the main highlight in this chapter are the raw Spring MVC 4 components. Also, it has no Spring security attached to it from the core, so there are no login/logout transaction for the user. All controllers in the PWP use a lot of @ModelAttribute and @SessionAttributes data.

The @ModelAttribute data are actually the same with request attributes. These are objects created from one single request dispatching. Moreover, these data are also called request-scoped data, which means that these data values are only valid within one request-response transaction.

One use of @ModelAttribute is to bind the form domain object to the form view page. On an incoming request transaction, any models with @ModelAttributes are called before any controller handler method. The following initForm() method is one example of this scenario.

@RequestMapping(method=RequestMethod.GET) 
  public String initForm(Model model, 
  @ModelAttribute("profesionalForm") 
  Professional professionalForm) { 
    return "professional_update"; 
  } 
 
@RequestMapping(method=RequestMethod.GET) 
  public String initForm(Model model) { 
    Professional professionalForm = new Professional(); 
 
    model.addAttribute("professionalForm", professionalForm); 
    references(model); 
    return "professional_update"; 
  } 
  public void references(Model model) { 
    List<String> hobbiesList = new ArrayList<String>(); 
    hobbiesList.add("Not Applicable"); 
    hobbiesList.add("Singing"); 
    hobbiesList.add("Painting"); 
    hobbiesList.add("Traveling"); 
    hobbiesList.add("Writing"); 
    hobbiesList.add("Swimming"); 
    model.addAttribute("hobbiesList", hobbiesList); 
 
    List<String> readingsList = new ArrayList<String>(); 
    readingsList.add("Not Applicable"); 
    readingsList.add("Novel"); 
    readingsList.add("Magazine"); 
    readingsList.add("Newspaper"); 
    readingsList.add("Diaries"); 
    model.addAttribute("readingsList", readingsList); 
 
    List<String> educLevelList = new ArrayList<String>(); 
    educLevelList.add("Not Applicable"); 
    educLevelList.add("Doctoral"); 
    educLevelList.add("Masters"); 
    educLevelList.add("College"); 
    educLevelList.add("Vocational"); 
    educLevelList.add("High School"); 
    model.addAttribute("educLevelList", educLevelList); 
  } 

To initialize the @ModelAttribute, it must be injected with an object value just like we have in the PWP project:

@ModelAttribute("greetings") 
  public List<String> getGreetings() { 
    return Greetings.allGreets(); 
  } 

The @SessionAttributes, on the other hand, are used by the controller to declare session objects during session handling. Equally, these attributes are the session attributes in a typical JEE web component. As long as the session is not terminated, session data are always accessible for update and retrieval. Sessions were used in the PWP project to store values for all the dynamic content transactions. Here is a code snippet that shows how to declare, initialize and update values that are @SessionAttributes.

@Controller 
@SessionAttributes("posts") 
@RequestMapping("pwp") 
public class IndexController { 
 
  @ModelAttribute("posts") 
  public List<PostMessage> newPosts() { 
    return initPost(); 
  } 
 
  @RequestMapping(value="/index", method=RequestMethod.GET) 
  public String getIndex(Model model,  @ModelAttribute("posts") 
    List<PostMessage> posts, 
    @ModelAttribute("postForm") PostMessage postForm) { 
 
      Home home = new Home(); 
      home.setMessage(initMessage()); 
      home.setQuote(initQuote()); 
      model.addAttribute("home",  home); 
 
      if(posts == null) posts = newPosts(); 
      if(validatePost(postForm)) { 
        postForm.setDatePosted(new Date()); 
        posts.add(postForm); 
      } 
 
      model.addAttribute("posts",  posts); 
      return "index"; 
    } 
    // Other codes refer to sources 
} 

The @SessionAttributes are declared on the controller level and are initialized as with any @ModelAttribute. Always initialize the session data to avoid the following error:

Servlet.service() for servlet [pwp] in context with path [/ch01] threw exception [Expected session attribute 'posts'] with root cause
org.springframework.web.HttpSessionRequiredException: Expected session attribute 'posts'

In order for the service operations to access the session attribute argument, be sure to have a @ModelAttribute parameter on the local parameter of the service depicting the attribute data:

public String getIndex(Model model,  @ModelAttribute("posts") 
  List<PostMessage> posts, 
  @ModelAttribute("postForm") PostMessage postForm) { 
  } 

These two attributes trigger the information workflow of the PWP project, even without the help of any web services or data store.

Form domain objects

Binding to the form view using @ModelAttribute, forms domain objects that are plain POJOs, and are used to save request parameter values from the user. Sometimes these objects are also called form data models. See the following domain:

package org.packt.personal.web.portal.model.form; 
 
public class Home { 
 
  private String message; 
  private String quote; 
 
  public String getMessage() { 
    return message; 
  } 
 
  public void setMessage(String message) { 
    this.message = message; 
  } 
 
  public String getQuote() { 
    return quote; 
  } 
 
  public void setQuote(String quote) { 
    this.quote = quote; 
  } 
} 

Instantiation of this model will be found in the initForm() method and the binding to the form view page will be implemented using the Spring Form Taglib directive:

<%@ taglib prefix="form"  uri="http://www.springframework.org/tags/form"%> 

The Spring MVC <form> tag has its own form components that can be readily mapped to the setters of the form domain objects. These topics will be highlighted in Chapter 3Student Management Portal (SMP), of this book. The following JSP code snippet shows how the binding is done through the <form> tag:

<form:form commandName="homeForm" method="post"> 
  <div class="form_settings"> 
    <!-- insert the page content here --> 
    <h2>Update Inspirational Message</h2> 
    <p><form:textarea path="message" rows="8" cols="50"/></p> 
    <span><form:errors path="message" cssStyle="color:      #ff0000; "/></span> 
    <br/> <br/> <br/> 
 
    <h2>Update Best Quote (Required)</h2> 
    <p><form:textarea path="quote" rows="8" cols="50"/></p> 
    <span><form:errors path="quote"  cssStyle="color:      #ff0000; "/></span>  
    <br/> <br/> <br/> 
 
    <p style="padding-top: 15px; padding-left: 20px"><input      class="submit"  
    type="submit" value="Update Home Page"></p> 
  </div> 
  </form:form> 

There are instances when a form view page contains several request parameters which need to be subdivided into groups.

Form domain objects

Given this situation, the best strategy is to decompose the huge flat domain POJO into several specific form domain models, each containing related data. Then, create a main POJO component class, which will hold all smaller domain models. This class will be represented as the form-backing object for the form view. A sample implementation of the preceding content page is shown as follows:

package org.packt.personal.web.portal.model.form; 
 
public class Personal { 
 
  private Biography biography; 
  private Education education; 
 
  public Biography getBiography() { 
    return biography; 
  } 
  public void setBiography(Biography biography) { 
    this.biography = biography; 
  } 
  public Education getEducation() { 
    return education; 
  } 
  public void setEducation(Education education) { 
    this.education = education; 
  } 
} 
 
package org.packt.personal.web.portal.model.form; 
import java.util.Date; 
import java.util.List; 
 
public class Biography { 
  private String firstName; 
  private String lastName; 
  private Integer age; 
  private Date birthDate; 
  private String location; 
  private String country; 
  private List<String> hobbies; 
  private List<String> readings; 
  // The getters and the setters 
} 
 
package org.packt.personal.web.portal.model.form; 
public class Education { 
 
  private String educLevel; 
  private String institution; 
  private String degree; 
  private String specialization; 
  private Integer year; 
 
  // The getters and the setters 
} 

The binding of the component will be quite different compared to the usual domain model. To bind all biography attributes to the form components, it is important to access first the getter method of the biography object, then through this we can now access all the setters of its attributes. The following example is a clear picture of the complicated binding:

<form:form commandName="personForm" method="post"> 
  <div class="form_settings"> 
  <!-- insert the page content here --> 
 
    <h2>Update Personal Information</h2> 
    <table style="width:100%; border-spacing:0;"> 
    <tr><td>First Name (*)</td> 
      <td><form:input path="biography.firstName"/></td> 
      <td><form:errors path="biography.firstName" cssStyle="color:        #ff0000"/></td> 
    </tr> 
    <tr><td>Last Name (*)</td> 
      <td><form:input path="biography.lastName"/></td> 
      <td><form:errors path="biography.lastName" cssStyle="color:        #ff0000"/> 
    </tr> 
    <!-- Rest of the script in the sources --> 
  </table> 
 
  <!-- Rest of the code in sources --> 
</form:form> 

The ViewResolver and view configuration

The interface ViewResolver is responsible for the mapping of the view names to the actual view pages. It also provides the view interface, which addresses the request of a view to the view technology. In this PWP project, all of our pages are written in JSP-JSTL so the view interface used is org.springframework.web.servlet.view.JstlView. The project's view resolver is implemented inside the Spring container in this way:

<bean id="viewResolver" 
  class="org.springframework.web.servlet.view.   ResourceBundleViewResolver"> 
  <property name="basename"> 
    <value>config.views</value> 
  </property> 
</bean> 

The views are also declared in the custom property file ./src/config/views.properties:

hello.(class)=org.springframework.web.servlet.view.JstlView 
hello.url=/jsp/hello_world.jsp 
 
index.(class)=org.springframework.web.servlet.view.JstlView 
index.url=/jsp/index.jsp 
 
index_update.(class)=org.springframework.web.servlet.view.JstlView 
index_update.url=/jsp/index_update.jsp 
 
// See the sources 

There are three popular generic ViewResolver implementations that developers always use and these are:

  • InternalResourceViewResolver: This is implemented whenever all the actual view pages are stored inside /WEB-INF/jsp. It has two sets of properties, namely a prefix or suffix that needs to be configured to generate the final view page URL.
            <bean 
              class="org.springframework.web.servlet.view.
                     InternalResourceViewResolver"> 
                <property name="viewClass" 
                value="org.springframework.web.servlet.view.JstlView"/> 
                <property name="prefix"> 
                  <value>/WEB-INF/</value> 
                </property> 
                <property name="suffix"> 
                  <value>.jsp</value> 
                </property> 
            </bean> 
    
  • The prefix indicates the location of the actual views, while the suffix tells the controller the allowed extension of all the actual pages. By default, InternalResourceViewResolver resolves the view names into view objects of type JstlView if the JSTL library is present in the classpath. If the view template is not the default, the viewClass property must be explicitly declared and mapped to other view templates like  org.springframework.web.servlet.view.tiles2.TilesView if tiles are to be used.
  • XmlViewResolver: If you want to declare each individual view-mapping to the actual page in an XML format, then this implementation best fits the project. A sample implementation is shown as follows:
        <bean id="helloWorld" 
          class="org.springframework.web.servlet.view.JstlView"> 
          <property name="url" 
            value="/WEB-INF/helloWorld.jsp" /> 
        </bean> 
  • ResourceBundleViewResolver: This implementation is the most flexible among the three, because the only thing needed here is a property containing all the view mappings. Moreover, one has the capability to combine different view technology in just one project, for the purpose of mixing together presentation layers.

A Spring MVC project can have more than resolvers, given that the order property in all definitions is defined to set order levels of 0 having the highest priority. The following code shows the ordering technique:

<bean 
  class="org.springframework.web.servlet.view.   InternalResourceViewResolver"> 
    <property name="prefix"> 
      <value>/WEB-INF/</value> 
    </property> 
    <property name="suffix"> 
      <value>.jsp</value> 
    </property> 
    <property name="order" value="2" /> 
</bean> 
 
<bean class= "org.springframework.web.servlet.view.XmlViewResolver"> 
  <property name="location"> 
    <value>/WEB-INF/views.xml</value> 
  </property> 
  <property name="order" value="1" /> 
</bean> 
 
<bean class= "org.springframework.web.servlet.view.ResourceBundleViewResolver"> 
  <property name="basename" value="views" /> 
  <property name="order" value="0" /> 
</bean> 

By convention, the InternalResourceViewResolver is always given the least priority because it takes a little time to map the view name directly to the actual pages before all the remaining resolvers. This might give conflict to other mappings if other resolvers are not fast enough in mapping views.

Actual view pages

The view template used in this project is JSP-JSTL, since the view interface used to map to JSP pages is org.springframework.web.servlet.view.JstlView. It is no longer recommended to use scriptlets.

Obviously, the actual view pages use some EL language components like the implicit object sessionScope. EL language is part of the jsp-api.jar libraries, so it is still acceptable to use its components. Moreover, we also used some JSTL tags like <c:out/> and <c:url/>. The tag <c:out/> is always recommended to output values of EL expression ${}, especially in generating reports wherein lots of the data are handled by EL expressions. The attribute escapeXml means that all words that are HTML tags will be captured, and thus they will be rendered on the page as HTML components. But most importantly, redirection implemented inside the view page must use URL rewriting so that when cookies are cut-off, the session data will still be shared by all controllers and views.

Validating Form Data

All form domain objects must be validated using the org.springframework.validation.Validator interface and annotations supported by JSR 303. The validation interface is implemented to create a set of validation rules as per the form view. A sample implementation used in PWP's home content page is shown as follows:

package org.packt.personal.web.portal.validator; 
 
import org.packt.personal.web.portal.model.form.Home; 
import org.springframework.stereotype.Component; 
import org.springframework.validation.Errors; 
import org.springframework.validation.ValidationUtils; 
import org.springframework.validation.Validator; 
 
public class IndexValidator implements Validator { 
  @Override 
  public boolean supports(Class<?> clazz) { 
    return Home.class.equals(clazz); 
  } 
 
  @Override 
  public void validate(Object obj, Errors errors) { 
    Home homeForm = (Home) obj; 
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, 
      "message", "message.empty"); 
    ValidationUtils.rejectIfEmptyOrWhitespace(errors,  
      "quote", "quote.empty"); 
 
    if(homeForm.getMessage().length() > 500) { 
      errors.rejectValue("message", 
        "message.maxlength"); 
    } 
    if(homeForm.getMessage().length() < 50) { 
      errors.rejectValue("message", 
        "message.minlength"); 
    } 
 
    if(homeForm.getQuote().length() > 500) { 
      errors.rejectValue("quote", "quote.maxlength"); 
    } 
    if(homeForm.getQuote().length() < 50) { 
      errors.rejectValue("quote", "quote.minlength"); 
    } 
  } 
 
} 

It validates checks if the user entered a content message and quotes greater than 50, but not greater than 500 alphanumeric. The validator interface has two abstract methods to implement, namely:

  • public boolean supports(): This method checks what type of @ModelAttribute object is being validated. @SessionAttributes are also included in this Boolean method.
  • public void validate(): If the preceding method confirms correctly the @ModelAttribute to be validated, this method will be executed next, dealing with all data values of the domain object.

Validators are components of the Spring MVC project. Spring MVC 4 uses the @Autowired stereotype to call the instance of the validator in the controller class. To enable the validator, the setValidator() method of org.springframework.web.bind .WebDataBinder has to be invoked inside the initBinder() method. To avoid complications, it is recommended to set one validator per initBinder() since we can create more than one initBinder() inside a form controller.

For situations like in PWP where both the @SessionAttributes and @ModelAttribute are utilized by the operations, initBinder() is recommended to be explicitly mapped to the specific attribute for the validator. Otherwise, the following exception shown will be encountered:

SEVERE: Servlet.service() for servlet [pwp] in context with path [/ch01] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Invalid target for Validator [org.packt.personal.web.portal.validator.IndexValidator@5b4ca52d]: undefault] with root cause
java.lang.IllegalStateException: Invalid target for Validator [org.packt.personal.web.portal.validator.IndexValidator@5b4ca52d]: undefault

To retrieve the result of the validation on a @ModelAttribute as per initBinder(), be sure to use the @Validated stereotype with the model argument declared in the submitForm() method. Following is a code that shows how to declare and enable validation in a form controller:

@Autowired 
  private Validator indexValidator; 
 
  @InitBinder("homeForm") 
  public void initBinder(WebDataBinder binder) { 
    binder.setValidator(indexValidator); 
  } 
 
  @RequestMapping(method=RequestMethod.POST) 
  public String submitForm(Model model,    @ModelAttribute("homeForm") @Validated Home homeForm,    BindingResult binding) { 
    model.addAttribute("homeForm", homeForm); 
    String returnVal = "index"; 
    if(binding.hasErrors()) { 
      returnVal = "index_update"; 
    } else { 
      model.addAttribute("homeSess", homeForm); 
      model.addAttribute("statusSess", "undefault"); 
    } 
    return returnVal; 
  } 

Validation using JSR 303

Aside from custom validation using the validator interface, Spring 4.x container supports annotations under the JSR 303 specifications that are applied directly to Java beans, used by the classes to impose specific validation rules. The following EmailController uses @NotNull to check if the two objects are not null, otherwise an error will be detected by the BindingResult.

@Controller 
@RequestMapping("/pwp/contact") 
public class EmailController { 
 
  @NotNull 
  @Autowired 
  private SimpleMailMessage emailTemplate; 
 
  @NotNull 
  @Autowired 
  private JavaMailSender emailSender; 
  // See the sources 
} 

Aside from @NotNull, annotations like @Pattern, and @Size are also widely used in string matching and collection size restrictions, respectively.

Domain data type conversion and filtering

The main purpose of the initBinder() is not purely to validate, but to bind request parameter data to the form domain model. It checks if the request parameter data matches the type of variables in the form-backing object. It provides conversion processes to data in order to avoid type mismatch and other related exceptions. The method has built-in property editors that you can use to check types. Some are custom editors of the type  java.beans.PropertyEditorSupport that check complicated matches with added custom transactions.

In the Personal portal page, there are data that needs to be converted into proper object types like age and birth date.

Domain data type conversion and filtering

Remember that request parameter data are all, by default, String objects. The custom property editor can be helpful in converting String data to other types, just to fit in the form-backing object's setter methods. Following is a custom editor for this page:

package org.packt.personal.web.portal.converter; 
import java.beans.PropertyEditorSupport; 
 
public class AgeConverter extends PropertyEditorSupport { 
 
  @Override 
  public void setAsText(String text) throws 
  IllegalArgumentException { 
    Integer age = 0; 
    try { 
      age = Integer.parseInt(text.trim()); 
    } catch(Exception e) { 
      age = 18; 
    } 
    setValue(age); 
  } 
} 
 
package org.packt.personal.web.portal.converter; 
 
import java.beans.PropertyEditorSupport; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
 
public class BirthDateConverter extends PropertyEditorSupport { 
 
  @Override 
  public void setAsText(String text) throws 
  IllegalArgumentException { 
    SimpleDateFormat format = new 
    SimpleDateFormat("mm/yy/dd"); 
    Date birthDate; 
    try { 
      birthDate = format.parse(text.trim()); 
    } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      birthDate = new Date(); 
    } 
    setValue(birthDate); 
  } 
} 

E-mail configuration

The Reach Out page opens an electronic communication between the portal owner and the portal reader or user. The Spring Framework supports e-mail operations with the org.springframework.mail package as the root level package with the following API classes:

  • MailSender: The central interface for sending e-mails is the MailSender interface.
  • SimpleMailMessage: The simple value object encapsulating the properties of a simple mail such as from and to (plus many others) is the class.
  • MailException: The root exception of all e-mail checked exceptions which provide a higher level of abstraction over the lower level mail system exceptions.
  • JavaMailSender: The interface that adds specialized JavaMail features such as MIME message support to its superclass MailSender interface.
  • MimeMessageHelper: A class that comes in pretty handy when dealing with JavaMail messages without using verbose JavaMail APIs.
  • MimeMessagePreparator: A callback interface for the preparation of JavaMail MIME messages.

This project sends three forms of e-mail template, namely the basic text-based e-mail, HTML-based e-mail and template-based e-mail. Following is PWP's way of sending an HTML-based e-mail.

public void sendMailHTML(Email emailForm) { 
  String  fromEmail = emailForm.getSendTo(); 
  String toEmail = emailForm.getSendTo(); 
  String emailSubject = emailForm.getSubject(); 
  String emailBody = emailForm.getMessage(); 
 
  MimeMessage mimeMessage = 
  emailSender.createMimeMessage(); 
  try { 
    MimeMessageHelper helper = new 
    MimeMessageHelper(mimeMessage, true, "utf-8"); 
    mimeMessage.setContent("<i><b>"+emailBody  
    +"</b></i>", "text/html"); 
    helper.setFrom(fromEmail); 
    helper.setTo(toEmail); 
    helper.setSubject(emailSubject); 
 
  } catch (MessagingException e) {} 
  /* 
  uncomment the following lines for attachment 
  FileSystemResource 
  file = new FileSystemResource("sample.jpg"); 
  helper.addAttachment(file.getFilename(), file); 
  */ 
 
  emailSender.send(mimeMessage); 
  System.out.println("Mail sent successfully."); 
 
} 

The Personal Web Portal (PWP) project

This chapter highlighted how to create a simple Spring MVC project using only its core components. Moreover, the chapter highlighted some of the components used by the PWP that can be used also by anybody to start learning Spring MVC from its core. Learning core components is essential to establish better understanding on how the base framework works, starting from configuring the controller, up to the implementation of PropertyEditorSupport for data binding enhancement and object type conversion. This chapter has given a picture of how to start a base Spring MVC project.

Following are full web pages of the PWP:

  • Let us look at the home page:
    The Personal Web Portal (PWP) project
  • Now let's look at the personal page:
    The Personal Web Portal (PWP) project
  • Now, the professional page:
    The Personal Web Portal (PWP) project
  • And finally the reach out page:
    The Personal Web Portal (PWP) project

    Note

    Web design theme

    The theme used by this project is inspired by, and based on, templates from http://creativecommons.org.

Challenge yourself

Create a personal portfolio website using Spring MVC. The site should consist of the following pages:

  • Home page: Consists of your picture, biography, academic information and other personal-related information.
  • Update page: Updates the information presented on the homepage. See to it that the home page is always updated once this is executed.
  • Contact Us: Provides e-mail support for those who want to email the owner.

Summary

Using the basic Spring Framework 4.x APIs, web portal creators can create their own platform to promote their personal philosophy, business, ideology, religion, and other concepts. Although it is an advantage to use existing portal platforms made in other language like PHP and Python, it is still fulfilling to design and develop our own portal based on an open-source framework. The PWP is just prototype software that needs to be upgraded to have a backend database, security, and other social media plugins, in order to make the software commercially competitive.

The next chapter will be about creating a simple document repository focusing on document management. If your personal web portal needs to have a Dropbox-like feature for any types of documents, then the next chapter will help you build that feature.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • *Learn all the details of implementing Spring 4.x MVC applications from basic core platform construction to advanced integration implementations
  • *Gain a complete reference guide to implementing the controllers, models, views, view resolvers, and other service-related components to solve various real-world problems
  • *Discover the possible optimal solutions for developers and experts to build enterprise and personal web-based applications
  • *Create a Spring MVC application that has a validation process and exception handling with the HTTP status codes

Description

Spring MVC is the ideal tool to build modern web applications on the server side. With the arrival of Spring Boot, developers can really focus on the code and deliver great value, leveraging the rich Spring ecosystem with minimal configuration. Spring makes it simple to create RESTful applications, interact with social services, communicate with modern databases, secure your system, and make your code modular and easy to test. It is also easy to deploy the result on different cloud providers. This book starts all the necessary topics in starting a Spring MVC-based application. Moving ahead it explains how to design model objects to handle file objects. save files into a data store and how Spring MVC behaves when an application deals with uploading and downloading files. Further it highlights form transactions and the user of Validation Framework as the tool in validating data input. It shows how to create a customer feedback system which does not require a username or password to log in. It will show you the soft side of Spring MVC where layout and presentation are given importance. Later it will discuss how to use Spring Web Flow on top of Spring MVC to create better web applications. Moving ahead, it will teach you how create an Invoice Module that receives and transport data using Web Services By the end of the book you will be able to create efficient and flexible real-time web applications using all the frameworks in Spring MVC.

Who is this book for?

This book is for competent Spring developers who wish to understand how to develop complex yet flexible applications with Spring MVC. You must have a good knowledge of JAVA programming and be familiar with the basics of Spring.

What you will learn

  • *Set up and configure the Spring 4.x MVC platform from ground level up using the basic Spring Framework 4.x APIs
  • *Study requirements and manage solutions on file uploading transactions in Spring 4.x applications *Configure, , and test Spring integration to the Hibernate, MyBatis, and JPA frameworks for database transactions
  • *Properly implement exception handlers and audit trails in Spring MVC applications
  • *Generate reports using JFreeChart, Google Charts, JasperReports, DynamicReports, FreeMarker, Velocity, and Spring's API known as ContentNegotiatingViewResolver
  • *Configure security and flexibility by adding Captcha, Spring Security, Spring Flow, Spring Portlets, JTA to improve data management performance
  • *Implement web services using Spring's RESTful implementation and other service-oriented integration plugins
  • *Design and implement a Spring 4.x application using AngularJS, ExtJs, Twitter Bootstrap, and Spring Mobile for responsive web design
Estimated delivery fee Deliver to Australia

Economy delivery 7 - 10 business days

AU$19.95

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Last updated date : Feb 11, 2025
Publication date : Jul 29, 2016
Length: 490 pages
Edition : 1st
Language : English
ISBN-13 : 9781785888274
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Redeem a companion digital copy on all Print orders
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Australia

Economy delivery 7 - 10 business days

AU$19.95

Product Details

Last updated date : Feb 11, 2025
Publication date : Jul 29, 2016
Length: 490 pages
Edition : 1st
Language : English
ISBN-13 : 9781785888274
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
AU$24.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
AU$249.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just AU$5 each
Feature tick icon Exclusive print discounts
AU$349.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just AU$5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total AU$ 227.97
Spring MVC Cookbook
AU$83.99
Spring MVC Blueprints
AU$75.99
Spring MVC Beginner's Guide
AU$67.99
Total AU$ 227.97 Stars icon

Table of Contents

10 Chapters
1. Creating a Personal Web Portal (PWP) Chevron down icon Chevron up icon
2. Electronic Document Management Systems (EDMS) Chevron down icon Chevron up icon
3. Student Management Portal (SMP) Chevron down icon Chevron up icon
4. Human Resource Management System (HRMS) Chevron down icon Chevron up icon
5. Customer Feedback System (CFS) Chevron down icon Chevron up icon
6. Hotel Management System (HMS) Chevron down icon Chevron up icon
7. Online Cart System (OCS) Chevron down icon Chevron up icon
8. Enterprise Resource Planning (ERP) Chevron down icon Chevron up icon
9. Bus Ticketing System (BTS) Chevron down icon Chevron up icon
10. Social Task Management System (STMS) Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
(3 Ratings)
5 star 33.3%
4 star 33.3%
3 star 33.3%
2 star 0%
1 star 0%
Abdelkafi Aug 10, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I had the pleasure to participate to the book review. The quality of the draft edition was simply amazing.Spring MVC framework is a Swiss army knife and this book provides pertinent use cases with implementation details.Even if you are an experimented Java/JEE developer, this book will surprise you by some features you don't yet tried or implemented with Spring MVC.I'm sure you won't regret buying it.
Amazon Verified review Amazon
Michael N. Oliver Sep 29, 2017
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Using blueprints has several benefits. One is the simple fact you save time in developing software, especially when there is a close resemblance to one of the example blueprints. Another is the standardization that comes from using the blueprints. That standardization leads to reduced costs and time to maintain the solutions based on the blueprints.
Amazon Verified review Amazon
Michael Oct 07, 2016
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
For me, this book has a same problem like "Spring MVC Cookbook" - too many topics, cases and technologies (which not so related to Spring).Or better to say, that all of cases were described not so precisely or in detail.I think, the book should be bigger, or concentrate on main subject only - in this case it's possible to learn something. Besides it's a wasting of time.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the digital copy I get with my Print order? Chevron down icon Chevron up icon

When you buy any Print edition of our Books, you can redeem (for free) the eBook edition of the Print Book you’ve purchased. This gives you instant access to your book when you make an order via PDF, EPUB or our online Reader experience.

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
Modal Close icon
Modal Close icon