JavaTMP Bootstrap Template Documentation Index

JavaTMP-User-Starter Project Version

JavaTMP-User-Starter project is an advanced dynamic Java Bootstrap LTR/RTL multi languages User Management Web application Template derived from JavaTMP-Static-Ajax modified and developed to provide a dynamic features built mainly using Java Servlet 4.0 and JSP 2.3 and deployed on Apache tomcat 9 with support for data persistent using Mysql Database Management System through java Persistent API and hibernate JPA implementation.

JavaTMP-User-Starter porject is a dynamic Java Bootstrap LTR/RTL multi languages User Management Web Application Version of our Java starter version JavaTMP-Static-Ajax customized to provide a user specific features built mainly using Java Servlet 4.0 and JSP 2.3 and deployed on Apache tomcat 9 and it is a Netbeans IDE 8.2 project, so you can directly import and open it there. The Online Dynamic Java Bootstrap User Management Web Application provides a running version of this template war file on tomcat 9.

It depends mainly on the following external backend java opensource libraries to provide a dynamic web application features with custom web MVC for serving JSP pages and handling Servlet requests:

JavaTMP-User-Starter project is a dynamic java web application providing a simple users management demo. The following list provides the main features of Dynamic Java Bootstrap Users Management web application Template version JavaTMP-User-Starter Project:

JavaTMP-User-Starter Project Folder Structure

The JavaTMP-User-Starter project folder structure is the same as JavaTMP-Static-Ajax one with the following main contents of its folder root:

./JavaTMP-User-Starter
|---.eslintrc (ESLint plugin configuration file which contains directive and parameters to gulp-eslint gulp plugin)
|---.gitignore (git SCM meta file to exclude mainly ./node_modules and ./nbproject/private/ folders from versioning)
|---build.xml (Netbeans IDE auto generated ant build script. used to compile, build, package project through Netbeans IDE or manually by command line)
|---gulpfile.js (gulp's configuration file for automating front end resources and generate assets/dist JS/CSS files)
|---package.json (A Node.js's NPM meta file. This file holds various metadata relevant to the project)
+---conf
    ...
    |---build.sql (Oracle Mysql Database dump script to start the Users Web Application from)
+---lib (External backend Java libraries used in the project)
+---nbproject (Netbeans IDE metadata about project)
+---src (Java source code files like Servlets and services classes)
    +---conf
        |---MANIFEST.MF
        |---persistence.xml (Hibernate and JPA configuration to connect to remote database)
    +---java (Java Source codes)
+---test (Java source code classes for testing and future use)
\---web (Web specific resources like assets, WEB-INF, JSP folders and pages)
    +---META-INF
        |---context.xml (Web Application Context file for Application Server instructions)
    +---WEB-INF (Web Application HTML/JSP pages and resources)

./JavaTMP-User-Starter/build.xml file

A standard Netbeans Java Web project uses an IDE-generated Ant build script to build, run, debug, and distribute your project. The default NetBeans IDE project system is built directly on top of the Ant build system. All of the project commands, such as “Build Project” and “Run File in Debugger”, call targets in the project’s Ant script. You can therefore build and run your project outside the IDE exactly as it is built and run inside the IDE. Remember that the build.xml build script file only contains an import statement that imports targets from nbproject/build-impl.xml. Use the build.xml to override targets from build-impl.xml or to create new targets.

You do not need to be familiar with Ant to work with applications in the IDE. You can set all the basic compilation and runtime options in your project’s Project Properties dialog box and the IDE automatically updates the project’s Ant script. If you know how to work with Ant, you can customize a project’s Ant script directly or write your own Ant script for your project.

So, to build your project outside the IDE exactly as it is built make sure you install Ant or you added it to your global path and it is accessible from a command line. If you already install and develop using Netbeans IDE 8.2 it come with Ant distribution installed on [NetBeans 8.2 installation folder]/extide/ant/bin, So you can add it to global path environment variables.

ant clean

Running this command will remove the above build and dist folders.

ant compile

Running this command will compile and generate the above build folder with .class files in ./build/web/WEB-INF/classes folder, and ./web folder in ./build/web and ./lib in ./build/web/WEB-INF/lib folder.

ant dist

Running this command will generate build folder if it is not exist and create a war package file from./build/web folder in it. So for testing and developing purposes you can deploy this war in any standard Java Servlet container like tomcat 9. Note that we don’t use this war on our production online demo because we process and minificate JSP pages and remove all source code from it before deploy it on production. We create our production war file from a gulp task.

Read more about Ant and Netbeans IDE Building process:

./JavaTMP-User-Starter/gulpfile.js file

This is a gulp’s configuration file. gulp is a toolkit for automating painful or time-consuming tasks in your development workflow. We use gulp to automate our building process like generating JS/CSS. The main important gulp task is generate-dist which copy resources from node_module folder and combine them and compile and generate theme and template Javascript and CSS files and folders. We described it in details in JavaTMP-Static-Ajax Project Version documentation page.

./JavaTMP-User-Starter/lib folder

The lib folder contains external backend java libraries needed to compile and run the dynamic web application features. The libraries binary jars only move to WAR/WEB-INF/lib when we build and generate war file. Note that the libraries with its source code and java doc are registered with Netbeans IDE project when we import it in Netbeans IDE 8.2. the following tree provide lib folder contents:

./JavaTMP-User-Starter/lib
|---mysql-connector-java-8.0.14.jar
|---simplecaptcha-1.2.1.jar
+---antlr4
+---commons-beanutils-1.9.3
+---commons-collections-3.2.2
+---commons-lang-3.8.1
+---commons-logging-1.2
+---google-gson-2.8.5
+---handlebars-4.0.6
+---hibernate-5.4.1
+---jstl-1.2
+---slf4j

./JavaTMP-User-Starter/src folder

src contains sub folders conf and java which contains the Java source code of all backend classes of the JavaTMP-User-Starter template version like Servlets, Services, bean, Java Web listener, Java Web Context classes. The following tree provides its contents and followed by important java and Servlets classes description:

You should be familiar with the below java package structure as we will not describe it nor the Java servlets in details.

./JavaTMP-User-Starter/src/java
\---com
    \---javatmp
        +---i18n
        +---module
        |   +---activity
        |   +---content
        |   +---country
        |   +---dms
        |   +---event
        |   +---language
        |   +---message
        |   +---stats
        |   +---theme
        |   +---timezone
        |   \---user
        +---mvc
        |   +---adapter
        |   \---domain
        |       \---table
        +---util
        \---web
            +---controller
            +---filter
            |   \---util
            \---listener

com.javatmp.web.listener.JavaTMPHttpSessionListener class

The JavaTMPHttpSessionListener implements javax.servlet.ServletContextListener interface and annotated by @javax.servlet.annotation.WebListener annotation to provide a startup and shutdown procedures when we deploy or undeploy JavaTMP-User-Starter web application using ServletContextListener.contextInitialized and ServletContextListener.contextDestroyed methods.

It considers as a main method in the web application environment used normally for initializing global resources like Database connection pool or Datasource lookup. We don’t do any important things at startup nor shutdown of the web applicationunless than setting a UTC timezone and create a ServiceFactory instance.

com.javatmp.web.listener.JavaTMPHttpSessionListener class

The JavaTMPHttpSessionListener implements javax.servlet.http.HttpSessionListener interface and annotated by @javax.servlet.annotation.WebListener annotation to trigger when a session is created and destroyed on the application server. So Whenever a new session has been created a HttpSessionListener.sessionCreated method will be invoked and whenever a session has been invalidated a HttpSessionListener.sessionDestroyed method will be invoked by the application server. We don’t do any important things at creating or destroying of the session instances.

There is no distinct difference between session timeout and session invalidation from the perspective of the session object. Whenever it happens the HttpSessionListener.sessionDestroyed method will be invoked by the application server.

com.javatmp.web.filter package

A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. Filters typically do not themselves create responses, but instead provide universal functions that can be “attached” to any type of servlet or JSP page. read more about it in The Essentials of Filters.

Servlet filters may be declared and mapped using the WebFilter annotation, but there is no way to control filter ordering using annotations alone, read more about this issue on How to define servlet filter order of execution using annotations in WAR. However, you can mix annotations and web.xml to minimize the XML configuration by only declaring the filter mappings in the web.xml. Because we can not guarantee the compatibles in all Java application server we use ONLY web.xml file and the order of the chain is determined by the order in which matching filter mappings appear in the web.xml file.

This package contains classes for implements main filters used in the web application. We don’t use @javax.servlet.annotation.WebFilter annotation but instead declared and mapped them in ./web/WEB-INF/web.xml to force the order of their executions. the following list provides our filters with their descriptions in order of their executions:

com.javatmp.web.controller package

Java Servlet Classes package for all web application requests and responses. The servlets classes use com.javatmp.mvc.MvcHelper to marshal/unmarshal data or request dispatcher mechanism to forward request to specific JSP page in /WEB-INF/ folder. See above our list of dynamic features currently deploy in the JavaTMP-User-Starter project for usage and information about Java Servlets in this package. The outline classes in com.javatmp.web.controller package are:

com.javatmp.web.controller.IndexController class

The root path main Java Servlet class responsible for handling default root request. It uses an empty url-pattern string annotation instead of providing a welcome page with specific url pattern name. The complete source code of IndexController class is:

package com.javatmp.web.controller;

import ...;

@WebServlet("")
public class IndexController extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
    }
}
com.javatmp.web.controller.PagesController class

This class consider as a front controller servlet responsible for forwarding url requests for JSP pages inside WEB-INFO/pages/* folder that does not have specific servlet for handling its url. The following code provides its source code:

package com.javatmp.web.controller;

import ...;

@WebServlet("/pages/*")
public class PagesController extends HttpServlet {

    private final Logger logger = Logger.getLogger(getClass().getName());

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String requestPath = request.getPathInfo();
        String requestPage = "/WEB-INF/pages" + requestPath + ".jsp";
        logger.info("Request Page [" + requestPage + "]");
        request.getRequestDispatcher(requestPage).forward(request, response);
    }
}

com.javatmp.mvc package

The main parts of com.javatmp.mvc package are sub package com.javatmp.mvc.domain.table which provides a communication protocol And com.javatmp.mvc.MvcHelper class which provides static utilities methods for marshaling/unmarshaling AJAX and JSON requests and responses. The following are an overview of these important parts of this package:

com.javatmp.mvc.domain.table package

This package contains classes that define a communication protocol for various AJAX requests and JSON responses based on the JSON structure of jQuery Datatables plugin request parameters in server-side processing mode described in details in Server-side processing sent parameters section.

com.javatmp.mvc.MvcHelper class

This class provides static utilities methods for marshaling/unmarshaling AJAX and JSON requests and responses used almost in all Servlet classes.

com.javatmp.module package

This package provides The backend business logic classes implementation of project. It contains sub packages for each module used in the JavaTMP-User-Starter Web application. The services are created by class com.javatmp.util.ServicesFactory.

com.javatmp.util.ServicesFactory class:

It is a Factory instance for all services classes grouped in one class to be injected in the Application Context. Usually, An instance of ServicesFactory class is created at web application startup to provide a sharing factory for all users.

./JavaTMP-User-Starter/web folder

This folder contains everything related to front end resources and plugins and JSP pages for application and template AJAX requests and web.xml file. The following tree structure provides an outline of its contents with description and usages.

./JavaTMP-User-Starter/web
+---assets
    +---data (Static JSON files used in some plugin demo pages)
    +---dist (Output JS/CSS resource from gulp's task generate-dist)
        +---css
        +---fonts
        +---img
        +---js
    +---img (Static images used in the template)
    +---src (Source folder of front end resources like scss and js files)
        +---fonts
        +---js-src
        +---sass
        +---sass-rtl
+---META-INF
    |---context.xml
+---WEB-INF (Hidden and not accessible directly from the browser requests)
    |---index.jsp (Main JSP Page)
    |---web.xml
    +---pages
        +---content
        +---dms
        +---event
        +---home
        +---message
        +---system
        +---user

The main important JSP page in our dynamic Java Bootstrap template is index.jsp which was dispatched from com.javatmp.web.controller.IndexController Servlet class to the user. The following HTML code provides its contents:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html lang="${labels["global.language"]}" dir="${labels["global.direction"]}" class="javatmp-default-admin-layout">
    <head>
        <title>${labels["global.page.title"]}</title>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-all.min.css" rel="stylesheet" type="text/css"/>
        <link href='${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-print-all.min.css' rel='stylesheet' media='print' />

        <!-- Include directional support -->
        <c:if test="${labels['global.direction'] == 'ltr'}">
            <link id="themeStyleSheet" href="${pageContext.request.contextPath}/assets/dist/css/javatmp-${sessionScope.user.theme}.min.css" rel="stylesheet" type="text/css"/>
        </c:if>
        <c:if test="${labels['global.direction'] == 'rtl'}">
            <link id="themeStyleSheet" href="${pageContext.request.contextPath}/assets/dist/css/javatmp-${sessionScope.user.theme}-rtl.min.css" rel="stylesheet" type="text/css"/>
        </c:if>

        <!-- Include language support font -->
        <link href="${pageContext.request.contextPath}/assets/dist/css/font-family-${labels['global.language']}.min.css" rel="stylesheet" type="text/css"/>
    </head>
    <body class="sidebar-active">
        ...
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all-locale-${sessionScope.user.lang}.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            jQuery(function ($) {
                javatmp.init({
                    httpMethod: "GET",
                    dataType: "html",
                    updateURLHash: true,
                    defaultPassData: {_ajax: "ajax", _ajaxGlobalBlockUI: true, _handleAjaxErrorGlobally: true},
                    defaultOutputSelector: '.main-body-content-container',
                    defaultUrl: '${pageContext.request.contextPath}/pages/home',
                    floatDefault: "${labels['global.floatDefault']}",
                    floatReverse: "${labels['global.floatReverse']}",
                    direction: "${labels['global.direction']}",
                    isRTL: ${labels['global.direction'] == 'ltr' ? 'false' : 'true'},
                    contextPath: '${pageContext.request.contextPath}'
                });

                javatmp.user = {};
                javatmp.user.id = ${sessionScope.user.id};
                javatmp.user.lang = "${sessionScope.user.lang}";
                // force en as a moment locale for now
                moment.locale("en");
            });
        </script>
        ...
    </body>
</html>

Notes

Dynamic JSP Starter Pages

The starter Java Bootstrap default English LTR page that use the above generated combined files look like the following:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html lang="en" dir="ltr" class="javatmp-default-admin-layout">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-all.min.css" rel="stylesheet" type="text/css"/>
        <link href='${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-print-all.min.css' rel='stylesheet' media='print' />
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-default.min.css" rel="stylesheet" type="text/css"/>
        <!-- Include language support font -->
        <link href="${pageContext.request.contextPath}/assets/dist/css/font-family-en.min.css" rel="stylesheet" type="text/css"/>
        ...
    </head>
    <body class="sidebar-active">
        ...
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all-locale-en.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp.min.js" type="text/javascript"></script>
        ...
    </body>
</html>

And the starter Java Bootstrap default English RTL page that use the above generated combined files look like the following:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html lang="en" dir="rtl" class="javatmp-default-admin-layout">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-all.min.css" rel="stylesheet" type="text/css"/>
        <link href='${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-print-all.min.css' rel='stylesheet' media='print' />
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-default-rtl.min.css" rel="stylesheet" type="text/css"/>
        <!-- Include language support font -->
        <link href="${pageContext.request.contextPath}/assets/dist/css/font-family-en.min.css" rel="stylesheet" type="text/css"/>
        ...
    </head>
    <body class="sidebar-active">
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all-locale-en.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp.min.js" type="text/javascript"></script>
        ...
    </body>
</html>

And the starter Java Bootstrap default Arabic RTL page that use the above generated combined files look like the following:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!doctype html>
<html lang="ar" dir="rtl" class="javatmp-default-admin-layout">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-all.min.css" rel="stylesheet" type="text/css"/>
        <link href='${pageContext.request.contextPath}/assets/dist/css/javatmp-plugins-print-all.min.css' rel='stylesheet' media='print' />
        <link href="${pageContext.request.contextPath}/assets/dist/css/javatmp-default-rtl.min.css" rel="stylesheet" type="text/css"/>
        <!-- Include language support font -->
        <link href="${pageContext.request.contextPath}/assets/dist/css/font-family-ar.min.css" rel="stylesheet" type="text/css"/>
        ...
    </head>
    <body class="sidebar-active">
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp-plugins-all-locale-ar.min.js" type="text/javascript"></script>
        <script src="${pageContext.request.contextPath}/assets/dist/js/javatmp.min.js" type="text/javascript"></script>
        ...
    </body>
</html>

Generating Production JavaTMP-User-Starter.war file

Generating our online production Java Bootstrap User Web application war file is done using the following special gulp’s task steps (Make sure first that ant compile or ant dist is ran first because this task depends on the build folder generating from running ant script):

gulp.src([
    './JavaTMP-User-Starter/**/*',
    '!**/node_modules{,/**}',
    '!**/nbproject/private{,/**}',
    '!**/package-lock.json'
], {dot: true})
        .pipe(gulp.dest("temp/JavaTMP-User-Starter"));
gulp.src(['temp/JavaTMP-User-Starter/build/web/**/*'], {dot: true})
        .pipe(gulp.dest("temp/online-java-demo-starter"));
gulp.src(['temp/online-java-demo-starter/**/*.html', 'temp/online-java-demo-starter/**/*.jsp'], {dot: true})
        .pipe(htmlmin({collapseWhitespace: true,
            minifyCSS: true,
            minifyJS: true,
            removeComments: true,
            ignoreCustomComments: false,
            keepClosingSlash: true,
            ignoreCustomFragments: [/<%--[\s\S]*?--%>/, /<%@[\s\S]*?%>/, /\$\{[\s\S]*?\}/, /<fmt:[\s\S]+?\/>/, /<c:[\s\S]+?\/?>/, /<\/c:[\s\S]+?>/, /\{\{[\s\S]*?\}\}/]
        }))
        .pipe(gulp.dest("temp/online-java-demo-starter"));
gulp.src(['temp/online-java-demo-starter/**/*'], {dot: true})
        .pipe(chmod(0o644, true))
        .pipe(zip('JavaTMP-User-Starter.war'))
        .pipe(gulp.dest('temp'));

Installation and Deploying

Preparing Netbeans 8.2 Project

The JavaTMP-User-Starter project is a Netbeans IDE 8.2 project, so you can directly import and open it there for compilation and deploying

Preparing Oracle Mysql Database Management System

Although we use JPA with Hibernate implementation library for managing and wrapping connections and JDBC handling to provide standard interface for any database management, we tested and deployed our online demo version with Oracle Mysql Database, So we describe and prepare it as a standard database vendor to use in JavaTMP projects.

First of all make sure you install and prepare your Oracle Mysql Database management system in your local development machine and follow the documentation on their website.

Most Database parameters like database name, username and password should be saved and changed in ./JavaTMP-User-Starter/src/conf/persistence.xml file.

Login to your mysql database instance through the command line:

> mysql -u mysql_user -p

Create a new Database:

mysql > create database appdb;

Check your new created Database:

mysql > show databases;

Create the User

mysql > create user javatmpUser;

Grant privileges while assigning the password for javatmpUser:

mysql > grant all on appdb.* to ‘javatmpUser’@’localhost’ identified by ‘javatmpUserPassword’; or

mysql > GRANT all privileges ON appdb.* TO ‘javatmpUser’@’localhost’ WITH GRANT OPTION;

Note: The localhost field usually doesn’t have to be edited, but you can set it to the specific address.

The above example grants all privileges, obviously. But you will likely want to limit privileges under many circumstances. These parameters include select, insert, and delete, For example:

mysql > grant select, insert, delete, update on appdb.* to ‘javatmpUser’@’localhost’ identified by ‘javatmpUserPassword’;

mysql > GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, REFERENCES ON appdb.* to ‘javatmpUser’@’localhost’ identified by ‘javatmpUserPassword’;

always be sure to reload all the privileges and changes through the command:

mysql > FLUSH PRIVILEGES;

quit to import our database script to your local database instance appdb from console command line:

mysql -ujavatmpUser -pjavatmpUserPassword -D appdb < ./JavaTMP-User-Starter/conf/build.sql

Now, Your local database should be loaded with all mandatory data and demo users in your local Mysql database ‘appdb’ instance. check that by login to mysql and run the following command:

mysql > show tables;

JavaTMP Users Project Database Tables

The database schema contains the following tables:

Please refer to tables description and corresponding Java bean classes in com.javatmp.module package for more information about their fields and values.