Tagged with Scott Macdonald

Launch the new Digital Marketing Support Community

We are getting ready to launch the new Digital Marketing support community in mid-July 2013 (only a few weeks away). The new community will feature new CQ-based forums and new Digital Marketing help pages that contain resources such as a ‘Spot Light’ s…

Submitting Mobile Data to Adobe CQ using a Sling Post Servlet

You can create an Adobe CQ mobile form using JQuery Mobile API and submit the data to Adobe CQ using a Sling Post Servlet. When a mobile user fills in the form and clicks the submit button, form data is submitted to Adobe CQ.  However, instead of …

Developing a Spring MVC project using Maven, JSTL tags, and data persistence

This Scotts Digital Community article falls into a general programming discussion (as opposed to an Adobe Enterprise development article) and provides details on developing a Spring MVC application that persists data. You can create this Spring MVC project by using Maven and JSTL tags. For information about Spring MVC, see http://static.springsource.org/spring/docs/2.0.x/reference/mvc.html.

Assume, for example, that you want to create a Spring MVC project that saves, displays, and deletes customer data.

A Spring MVC application that supports saving, viewing, and deleting customer data
This development article guides you through how to create this Spring MVC project, including how to configure the Spring DispatcherServlet. Included in this article is the use of Spring annotations such as @Autowired. This annotation informs the Spring framework to use dependency injection on a constructor, class field, setter method or config method. 
The JavaServer Pages Standard Tag Library (JSTL) is a collection of  JSP tags which uses functionality common to JSP applications. For example, using a JSTL tag, you can iterate through a data collection and display the results within a web page. 
To create a Spring MVC project using Maven, perform these tasks:
1. Setup Maven in your development environment.
2. Create a Maven project structure.
3. Convert the Maven project to a Spring MVC project.
4. Build the Maven project.
5. Deploy the Maven project to an application server (in this development environment, the project is ran on Tomcat). 

SETUP MAVEN IN YOUR DEVELOPMENT ENVIRONMENT


You can use Maven to build and manage Java projects. One benefit of Maven is dependency management. What does this mean? Well — it means that Maven manages required JAR files that a Java project needs in its class path. Therefore instead of hunting through the Internet trying to find and download third-party JAR files to include in your class path, Maven will manage these dependencies for you.
You can download Maven 3 from the following URL:
After you download and extract Maven, create an environment variable named M3_HOME. Assign the Maven install location to this environment variable. For example:
C:\Programs\Apache\apache-maven-3.0.4
You can test to determine if Maven is properly setup by entering the following command into a command prompt:
%M3_HOME%\bin\mvn -version
This command provides Maven and Java install details and resembles the following message:
Apache Maven 3.0.4 (r1232337; 2012-01-17 03:44:56-0500)
Maven home: C:\Programs\Apache\Maven\apache-maven-3.0.4
Java version: 1.6.0_31, vendor: Sun Microsystems Inc.
Java home: C:\Programs\Java64-6\jre
Default locale: en_US, platform encoding: Cp1252
OS name: “windows 7”, version: “6.1”, arch: “amd64”, family: “windows”

CREATE A MAVEN PROJECT STRUCTURE

You can use a Maven archetype plugin to create a project. To create a Java application, you can  use the maven-archetype-quickstart plugin. The following example creates a Maven Java application project in the C:\apache-maven-3.0.4\ folder.
To create a Maven project structure:
1. Open the command prompt and go to the C:\apache-maven-3.0.4 directory.
2. Run the following Maven command:
mvn archetype:generate -DgroupId=com.sdc.controller -DartifactId=FirstController -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

You will see a Maven message similar to the following:

 [INFO] Using following parameters for creating project from Old (1.x) Archetype:
 maven-archetype-quickstart:1.0
[INFO] 
[INFO] Parameter: groupId, Value: com.sdc.controller
[INFO] Parameter: packageName, Value: com.sdc.controller
[INFO] Parameter: package, Value: com.sdc.controller
[INFO] Parameter: artifactId, Value: FirstController
[INFO] Parameter: basedir, Value: C:\apache-maven-3.0.4
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: C:\apache-maven-3.0.4\FirstController
[INFO] BUILD SUCCESS
[INFO] Total time: 3.347s
[INFO] Finished at: Sun Jan 20 16:49:18 EST 2013
[INFO] Final Memory: 8M/122M

This Maven command produces a basic project structure that contains a POM file and basic Java class.

The generated Maven POM file is located in the FirstController folder. Change this folder name to Customer and modify the folder structure under Customer to reflect the folder structure shown in the following illustration. Next, delete the folders under the java folder. New Java files are added in the following sections.

Under the java folder, create the following folder structure: java\com\springapp\mvc. These child folders correspond to the Java package named com.springapp.mvc that is used in this development article.

CONVERT THE MAVEN GENERATED PROJECT TO A SPRING MVC PROJECT

The next step is to convert the generated Maven project into a Spring MVC project. This involves performing the following tasks:
1. Add the Java classes to the com.springapp.mvc package.
2. Modify the POM file to include Spring MVC dependencies.
3. Add a data persistence XML configuration file to the resources folder.  
3. Add a new folder named webapp to the src/main folder. This folder contains the WEB-INF folder.

Add the User class 

Add a Customer class to the java\com\springapp\mvc folder that represents a Spring bean. This class uses the following annotations:
  • @Entity – indicates that this Spring bean is a persistent entity. 
  • @GeneratedValue - indicates a primary key property or field of an entity or mapped superclass in conjunction with the Id annotation.
  • @Basic – can be applied to a persistent property. In this example, first name, last name, and email fields are persisted. 
The following Java code represents the User class. 
package com.springapp.mvc;

import javax.persistence.*;

@Entity(name = “account”)
public class User{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Basic
    private String firstName;

    @Basic
    private String lastName;

    @Basic
    private String email;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String name) {
        this.firstName = name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Add the UserController class 

Add a UserController class to the java\com\springapp\mvc folder that represents a Spring MVC controller. A controller  is responsible for receiving requests from users and invoking services for business processing. This class contains the following annotations:
  • @Controller – indicates that this class is a MVC controller. 
  • @Autowired-  informs the Spring framework to use dependency injection
  • @RequestMapping – specifies that the corresponding method is a controller handler method.

    The following Java code represents the UserController class. 

    package com.springapp.mvc;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;

    @Controller
    public class UserController {
        @Autowired
        private UserRepository userRepository;

        @RequestMapping(value = “/”, method = RequestMethod.GET)
        public String listUsers(ModelMap model) {
            model.addAttribute(“user”, new User());
            model.addAttribute(“users”, userRepository.findAll());
            return “users”;
        }

        @RequestMapping(value = “/add”, method = RequestMethod.POST)
        public String addUser(@ModelAttribute(“user”) User user, BindingResult result) {

            userRepository.save(user);

            return “redirect:/”;
        }

        @RequestMapping(“/delete/{userId}”)
        public String deleteUser(@PathVariable(“userId”) Long userId) {

            userRepository.delete(userRepository.findOne(userId));

            return “redirect:/”;
        }
    }

    Add the UserRepository class

    Add the UserRepository class that extends org.springframework.data.jpa.repository.JpaRepository. The JpaRepository class lets a bean of this type modify data stored in the database.  
    The following Java code represents the UserRepository class.
    package com.springapp.mvc;

    import org.springframework.data.jpa.repository.JpaRepository;

    public interface UserRepository extends JpaRepository<User, Long> {
    }

    Modify the POM file to include Spring MVC dependencies

    Replace the POM that the Maven plug-in created with the following POM file. This new POM includes Spring dependencies that are required to use Spring MVC functionality. In addition, the dependency to use Hibernate functionality is also included. 
    <project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
     xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”>
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.springapp.mvc</groupId>
        <artifactId>Customer</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>SpringMVC Maven Webapp</name>
        <url>http://maven.apache.org</url>
    <properties>
            <spring.version>3.2.0.RELEASE</spring.version>
        </properties>
      <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>

            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.1</version>
                <scope>provided</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.8.2</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-jpa</artifactId>
                <version>1.2.0.RELEASE</version>
            </dependency>

            <dependency>
                <groupId>org.hibernate.javax.persistence</groupId>
                <artifactId>hibernate-jpa-2.0-api</artifactId>
                <version>1.0.0.Final</version>
            </dependency>

            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
                <version>3.6.10.Final</version>
            </dependency>

            <dependency>
                <groupId>org.hsqldb</groupId>
                <artifactId>hsqldb</artifactId>
                <version>2.2.9</version>
            </dependency>

            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>20080701</version>
            </dependency>

        </dependencies>

    </project>

    Add a data persistence XML configuration file to the resources folder

    Add a data persistence XML configuration file that lets the Spring MVC application persist data into a database. In the resources folder, create a sub folder named META-INF. Add an XML file named persistence.xml in the META-INF folder.
    The following XML represents the  persistence.xml configuration file. In this example, a HSQL database is used. Notice that values such as user name and password are specified using property elements.   
    <?xml version=”1.0″ encoding=”UTF-8″?>
    <persistence version=”2.0″ xmlns=”http://java.sun.com/xml/ns/persistence” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd”>
        <persistence-unit name=”defaultPersistenceUnit” transaction-type=”RESOURCE_LOCAL”>
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <properties>
                <property name=”hibernate.dialect” value=”org.hibernate.dialect.HSQLDialect” />
                <property name=”hibernate.connection.url” value=”jdbc:hsqldb:mem:spring” />
                <property name=”hibernate.connection.driver_class” value=”org.hsqldb.jdbcDriver” />
                <property name=”hibernate.connection.username” value=”sa” />
                <property name=”hibernate.connection.password” value=”” />
                <property name=”hibernate.hbm2ddl.auto” value=”create-drop” />
            </properties>
        </persistence-unit>
    </persistence>

    Add the webapp folder to the Maven project structure

    Add a new folder named webapp to the main folder. Add a subfolder named WEB-INF to the webapp folder. You add the following three files to this WEB-INF folder: web.xml, mvc-dispatcher-servlet.xml, and users.jsp (this file is located in a sub folder named pages). The users.jsp file calls the Java application logic defined within the UserController class.
    The web.xml file defines servlets for the web application (after all, a Spring MVC project is a web application). Within the web.xml file,  you specify a Spring MVC servlet. A Spring MVC servlet is based on org.springframework.web.servlet.DispatcherServlet. In the following example, the name of the Spring dispatcher servlet is mvc-dispatcher.
    The following XML code represents the web.xml file.
    <web-app version=”2.4″
    xmlns=”http://java.sun.com/xml/ns/j2ee” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
    xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd”>

    <display-name>Spring MVC Application</display-name>

        <servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
    </web-app>

    Notice the servlet-name element specifies mvc-dispatcher. This specifies the location of the mvc-dispatcher-servlet.xml. In this example, the name of the dispatcher servlet is mvc-dispatcher (this is the file that is created next). 

    The mvc-dispatcher-servlet.xml informs the Spring framework where to find the controller (in this article, the controller is the UserController  class. The dispatcher configuration uses the following element to specify the location of the controller:
    <context:component-scan base-package=”com.springapp.mvc”/>
    This XML element informs the Spring framework to search the com.springapp.mvc package for a controller. The following XML represents the mvc-dispatcher-servlet.xml file.
    <beans xmlns=”http://www.springframework.org/schema/beans”
           xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
           xmlns:context=”http://www.springframework.org/schema/context” xmlns:tx=”http://www.springframework.org/schema/tx”
           xmlns:jpa=”http://www.springframework.org/schema/data/jpa”
           xsi:schemaLocation=”http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd”>

        <context:component-scan base-package=”com.springapp.mvc”/>

        <bean class=”org.springframework.web.servlet.view.InternalResourceViewResolver”>
            <property name=”prefix” value=”/WEB-INF/pages/”/>
            <property name=”suffix” value=”.jsp”/>
        </bean>

        <jpa:repositories base-package=”com.springapp.mvc”/>

        <bean id=”entityManagerFactory” class=”org.springframework.orm.jpa.LocalEntityManagerFactoryBean”>
            <property name=”persistenceUnitName” value=”defaultPersistenceUnit”/>
        </bean>

        <bean id=”transactionManager” class=”org.springframework.orm.jpa.JpaTransactionManager”>
            <property name=”entityManagerFactory” ref=”entityManagerFactory” />
        </bean>

        <tx:annotation-driven transaction-manager=”transactionManager”/>
    </beans>

    The last file to create is the user.jsp file. In this example, place the JSP file in a folder named pages (this is a sub-folder to WEB-INF). This JSP invokes Java methods defined in the UserController.

    <!doctype html>
    <%@taglib uri=”http://www.springframework.org/tags” prefix=”spring” %>
    <%@taglib uri=”http://www.springframework.org/tags/form” prefix=”form” %>
    <%@taglib uri=”http://java.sun.com/jsp/jstl/core” prefix=”c” %>

    <html>
    <head>
        <meta charset=”utf-8″>
        <title>Spring MVC Application</title>

        <meta content=”IE=edge,chrome=1″ http-equiv=”X-UA-Compatible”>
        <meta name=”viewport” content=”width=device-width, initial-scale=1.0″>

        <link href=”http://twitter.github.io/bootstrap/assets/css/bootstrap.css” rel=”stylesheet”>
        <link href=”http://twitter.github.io/bootstrap/assets/css/bootstrap-responsive.css” rel=”stylesheet”>
    </head>

    <body>

    <div class=”container”>
        <div class=”row”>
            <div class=”span8 offset2″>
                <h1>Users</h1>
                <form:form method=”post” action=”add” commandName=”user” class=”form-horizontal”>
                <div class=”control-group”>
                    <form:label cssClass=”control-label” path=”firstName”>First Name:</form:label>
                    <div class=”controls”>
                        <form:input path=”firstName”/>
                    </div>
                </div>
                <div class=”control-group”>
                    <form:label cssClass=”control-label” path=”lastName”>Last Name:</form:label>
                    <div class=”controls”>
                        <form:input path=”lastName”/>
                    </div>
                </div>
                <div class=”control-group”>
                    <form:label cssClass=”control-label” path=”email”>Email:</form:label>
                    <div class=”controls”>
                        <form:input path=”email”/>
                    </div>
                </div>
                <div class=”control-group”>
                    <div class=”controls”>
                        <input type=”submit” value=”Add User” class=”btn”/>
                        </form:form>
                    </div>
                </div>

                <c:if test=”${!empty users}”>
                    <h3>Users</h3>
                    <table class=”table table-bordered table-striped”>
                        <thead>
                        <tr>
                            <th>Name</th>
                            <th>Email</th>
                            <th>&nbsp;</th>
                        </tr>
                        </thead>
                        <tbody>
                        <c:forEach items=”${users}” var=”user”>
                            <tr>
                                <td>${user.lastName}, ${user.firstName}</td>
                                <td>${user.email}</td>
                                <td>
                                    <form action=”delete/${user.id}” method=”post”><input type=”submit” class=”btn btn-danger btn-mini” value=”Delete”/></form>
                                </td>
                            </tr>
                        </c:forEach>
                        </tbody>
                    </table>
                </c:if>
            </div>
        </div>
    </div>

    </body>
    </html>

    In this example, notice that JSTL tags are used. In this example, for each user in the database, a new table HTML table row is created and the user.lastName and user.FirstName methods (defined in the User class) are invoked. 
    Each row also has a button defined by this HTML tag: input type=”submit”.  When clicked, notice that the delete method defined in the UserController class is invoked. This deletes the user record from the database. 
    Finally a new user is added to the database by clicking the Add User button. When the Add User button is clicked, the addUser method located in the UserController is invoked. 
    @RequestMapping(value = “/add”, method = RequestMethod.POST)
        public String addUser(@ModelAttribute(“user”) User user, BindingResult result) {

            userRepository.save(user);

            return “redirect:/”;
        }

    BUILD THE MAVEN PROJECT

    After you convert the generated Maven project to a Spring MVC project, you can build the artifact by using Maven. The artifact that is built is a WAR file, as specified in the POM file. In this example, the packaging element in the POM file specifies war:
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springapp.mvc</groupId>
    <artifactId>Customer</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringMVC Maven Webapp</name>
    <url>http://maven.apache.org</url>
    To create the artifact by running Maven, perform these steps:
    1.Start the Command Prompt.
    2. Change the directory to the location of POM file.
    3. Enter the following command: %M3_HOME%\bin\mvn clean package.
    4. The WAR file is placed in the target directory. In this example, the WAR file is named Customer-1.0-SNAPSHOT.war.


    DEPLOY THE WAR FILE TO TOMCAT

    Deploy the WAR file that was built in the previous step by placing it in the Tomcat\webapps folder. Restart Tomcat. Once Tomcat is started, you can view the Spring MVC application by entering the following URL:
    http://[server name]:[port]/Customer-1.0-SNAPSHOT/

    The following illustration shows the Spring MVC application in a web browser. 

    CONCLUSION

    This article walked you through how to set-up a Spring MVC project using Maven and highlighted how the dispatcher, controller and view work together. Once you understand this, you can start to work on more complex Spring MVC applications.

    ABOUT THE AUTHOR

    I (Scott Macdonald) am a Senior Digital Marketing Content and Community  lead at Adobe Systems with over 16 years in the high tech industry. I am also a programmer with knowledge in Java, JavaScript, C#,C++, HTML, XML and ActionScript. If  you would like to see more CQ or other Adobe Digital Marketing end to end walkthroughs like this, then leave a comment and let me know what content you would like to see.

    Creating gallery components that display digital assets stored in the CQ DAM

    You can create an interactive visual component that lets your AEM users engage with your Adobe CQ web site by viewing and clicking on images. When a user clicks on a thumbnail version of an image, a larger view of the image appears. In this workflow, t…

    Submitting Mobile Form Data to Adobe CQ

    You can create an Adobe CQ mobile form using JQuery Mobile API. When a mobile user fills in the form and clicks the submit button, form data is submitted to Adobe CQ. You can develop an OSGi bundle operation to process the submitted form data to meet y…

    Creating custom CQ email services

    You can create a custom CQ email service that lets CQ users send email messages from a CQ web page. To create a CQ email service, you develop an OSGi bundle that uses the Java Mail API. You can also develop a JSP that uses JQuery that calls the OSGi se…

    New CQ best practice articles now live!

    We’ve just published the following three CQ best practice articles: Migrating DITA XML data to Adobe CQ Integrating custom CQ widgets with third-party libraries Back up CQ authoring servers with no downtime These articles are the first few in the CQ best practices series. In the days to come, we’ll post more best practices, tips, [...]

    Integrating custom CQ widgets with third-party libraries

    Have you ever wondered how to create a custom CQ widget that performs tasks not available with out of the box CQ components. In this situation, you can create a CQ widget that uses third-party libraries that lets your CQ application perform custom task…

    Using JSONWriter objects to display Adobe CQ OSGi data

    You can create an org.apache.sling.commons.json.io.JSONWriter instance to invoke Adobe CQ OSGi bundle operations and display data within a JSP. A JSONWriter instance lets you define value and key methods to retrieve data. You can create an Adobe CQ com…

    Creating Adobe CQ bundles that consume web services

    You can create an Adobe CQ bundle that consumes data from a third-party web service and then display the data in a web page. For example, assume that you use Adobe CQ to create a web site for a government department that tracks weather information. In …


    Copyright © 2012 Adobe Systems Incorporated. All rights reserved.
    Terms of Use | Privacy Policy and Cookies (Updated)