Building DHTMLX Grid Panel User Interface with Spring MVC Rest and MongoDB Backend

Nowadays, there are so many choices when it comes to choosing a Javascript-based user interface for web-based applications. In my opinion, DHTMLx is among the best four GUI based frameworks. The other three frameworks I would highly recommend are Ext JS, SmartClient and Dojo Toolkit. There are several others which include Webix, jQuery UI and YUI (no longer being actively maintained) but these last few may not have quite the same flare as the top four.

In this tutorial we will show how easy it is to use DHTMLX dhtmlxGrid component while loading JSON data with Ajax pulling in data from the Spring MVC REST web service from our MongoDB data source. You will see how simple it is to create a visually appealing experience for your client(s) with minimal javascript coding.
Although we are using the Native JSON format for our data in this example, dhtmlxGrid can also load data using the following formats: JSON (2) formats, XML, CSV, Javascript Array and HTML table.

Getting Started

In order to run this tutorial yourself, you will need the following:

Libraries Required

For this project I am using Maven for Spring Framework for my build, but for those of you that prefer to simply copy the required libraries into your webapp/WEB-INF/lib; I am including the image below for your reference. In this REST web service I am using JSON so you will notice that a few of the Jackson libraries have been included in addition to the standard Spring MVC library dependencies.

spring mvc dhtmlx maven

Complete Project Overview

I have added the project overview to give you a full view of the structure and show you all files contained in this sample project.

spring mvc dhtmlx proj

RESTful Web Service End Points

1/SpringRestDhtmlxMongoDBExample/rest/employeesGETReturns a list of all the employees available in MongoDB
2/SpringRestDhtmlxMongoDBExample/rest/employee/{uid}GETReturn the employee based on the uid in MongoDB
3/SpringRestDhtmlxMongoDBExample/rest/employee/delete/{uid}DELETEDelete the employee in the MongoDB datastore based on the uid
4/SpringRestDhtmlxMongoDBExample/rest/employee/update/{uid}PUTUpdates the employee in the MongoDB datastore based on the uid
5/SpringRestDhtmlxMongoDBExample/rest/employee/createPOSTInserts the employee into the MongoDB datastore based on the contents of the form

EmployeeRepository for MongoDB DAO

package com.avaldes.dao;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.avaldes.model.Employee;

public class EmployeeRepository {
  public static final String COLLECTION_NAME = "employee";
    private MongoTemplate mongoTemplate;
  public void addEmployee(Employee employee) {
        if (!mongoTemplate.collectionExists(Employee.class)) {
        mongoTemplate.insert(employee, COLLECTION_NAME);
  public Employee getEmployeeByUID(String uid) {
      return mongoTemplate.findOne(
          Query.query(Criteria.where("uid").is(uid)), Employee.class, COLLECTION_NAME);
  public List<Employee> getAllEmployees() {
        return mongoTemplate.findAll(Employee.class, COLLECTION_NAME);
    public Employee deleteEmployee(String uid) {
      Employee Employee = mongoTemplate.findOne(
          Query.query(Criteria.where("uid").is(uid)), Employee.class, COLLECTION_NAME);
        mongoTemplate.remove(Employee, COLLECTION_NAME);
        return Employee;
    public Employee updateEmployee(String uid, Employee Employee) {
      Query query = new Query();
      Update update = new Update();
      update.set("manager_id", Employee.getManager_id());
      mongoTemplate.updateFirst(query, update, Employee.class);
      return Employee;

MultipleEmployeeResponse for DHTMLX specific JSON Format

I have created the MultipleEmployeeResponse class file in order to easily create the DHTMLX specific JSON format that is needed for the dhtmlxGrid. As you can see, there are a few fields at the beginning that have been added in order to satisfy that requirement.


import java.util.List;

import com.avaldes.model.Employee;

public class MultipleEmployeeResponse {
  private int total_count = 0;
  private int pos = 0;
  private List<Employee> data;
  public MultipleEmployeeResponse(List<Employee> data) { = data;
    total_count = data.size();
  public int getPos() {
    return pos;

  public void setPos(int pos) {
    this.pos = pos;

  public int getTotal_count() {
    return total_count;

  public void setTotal_count(int total_count) {
    this.total_count = total_count;

  public List<Employee> getData() {
    return data;
  public void setData(List<Employee> data) { = data;

Spring MVC RestController (

package com.avaldes.tutorial;

import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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;
import org.springframework.web.bind.annotation.ResponseBody;

import com.avaldes.dao.EmployeeRepository;
import com.avaldes.model.Employee;

 * Handles requests for the application home page.
public class RestController {
  private static final Logger logger = LoggerFactory.getLogger(RestController.class);
    private EmployeeRepository EmployeeRepository;
   * Simply selects the home view to render by returning its name.
  @RequestMapping(value = "/", method = RequestMethod.GET)
  public String home(Locale locale, Model model) {"Default Home REST page. The client locale is {}.", locale);
    Date date = new Date();
    DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
    String formattedDate = dateFormat.format(date);
    model.addAttribute("serverTime", formattedDate );
    return "status";
  @RequestMapping(value="/employees", method=RequestMethod.GET)
  public MultipleEmployeeResponse getAllEmployees() {"Inside getAllEmployees() method...");

    List<Employee> allEmployees = EmployeeRepository.getAllEmployees();
    MultipleEmployeeResponse response = new MultipleEmployeeResponse(allEmployees);
    return response;
  @RequestMapping(value="/employee/{uid}", method=RequestMethod.GET)
  public Employee getEmployeeByUID(@PathVariable("uid") String uid) {
    Employee myEmployee = EmployeeRepository.getEmployeeByUID(uid);
    if (myEmployee != null) {"Inside getEmployeeByUID, returned: " + myEmployee.toString());
    } else {"Inside getEmployeeByUID, UID: " + uid + ", NOT FOUND!");
    return myEmployee; 

  @RequestMapping(value="/employee/delete/{uid}", method=RequestMethod.DELETE)
  public Employee deleteEmployeeByUID(@PathVariable("uid") String uid) {
    Employee myEmployee = EmployeeRepository.deleteEmployee(uid);
    if (myEmployee != null) {"Inside deleteEmployeeByUID, deleted: " + myEmployee.toString());
    } else {"Inside deleteEmployeeByUID, UID: " + uid + ", NOT FOUND!");
    return myEmployee;
  @RequestMapping(value="/employee/update/{uid}", method=RequestMethod.PUT)
  public Employee updateEmployeeByUID(@PathVariable("uid") String uid, @ModelAttribute("employee") Employee employee) {
    Employee myEmployee = EmployeeRepository.updateEmployee(uid, employee);
    if (myEmployee != null) {"Inside updateEmployeeByUID, updated: " + myEmployee.toString());
    } else {"Inside updateEmployeeByUID, UID: " + uid + ", NOT FOUND!");
    return myEmployee;

  @RequestMapping(value="/employee/addEmployee", method=RequestMethod.POST)
  public Employee addEmployee(@ModelAttribute("employee") Employee employee) {
    if (employee.getUid() != null && employee.getUid().length() > 0) {"Inside addEmployee, adding: " + employee.toString());
    } else {"Failed to insert...");
    return employee;

The Model Class for Employee

package com.avaldes.model;

public class Employee {
  private String id;
  private String dn;
  private String uid;
  private String birth_date;
  private boolean isManager;
  private String employee_type;
  private String status;
  private String termination_date;
  private String title;
  private String first_name;
  private String last_name;
  private String department;
  private String location_code;
  private String full_name;
  private String country;
  private String company;
  private String phone;
  private String manager_id;
  private String designated_shopper;
  private String emergency_contact_primary;
  private boolean active_directory_role;
  private boolean lotus_notes_mail_role;
  private boolean is_doh_updated;
  private boolean is_dot_updated;
  private boolean reports_to_me;
  public String getId() {
    return id;

  public void setId(String id) { = id;

  public String getDn() {
    return dn;

  public void setDn(String dn) {
    this.dn = dn;

  public String getUid() {
    return uid;

  public void setUid(String uid) {
    this.uid = uid;

  public String getBirth_date() {
    return birth_date;

  public void setBirth_date(String birth_date) {
    this.birth_date = birth_date;

  public boolean isManager() {
    return isManager;

  public void setManager(boolean isManager) {
    this.isManager = isManager;

  public String getEmployee_type() {
    return employee_type;

  public void setEmployee_type(String employee_type) {
    this.employee_type = employee_type;

  public String getStatus() {
    return status;

  public void setStatus(String status) {
    this.status = status;

  public String getTermination_date() {
    return termination_date;

  public void setTermination_date(String termination_date) {
    this.termination_date = termination_date;

  public String getTitle() {
    return title;

  public void setTitle(String title) {
    this.title = title;

  public String getFirst_name() {
    return first_name;

  public void setFirst_name(String first_name) {
    this.first_name = first_name;

  public String getLast_name() {
    return last_name;

  public void setLast_name(String last_name) {
    this.last_name = last_name;

  public String getDepartment() {
    return department;

  public void setDepartment(String department) {
    this.department = department;

  public String getLocation_code() {
    return location_code;

  public void setLocation_code(String location_code) {
    this.location_code = location_code;

  public String getFull_name() {
    return full_name;

  public void setFull_name(String full_name) {
    this.full_name = full_name;

  public String getCountry() {
    return country;

  public void setCountry(String country) { = country;

  public String getCompany() {
    return company;

  public void setCompany(String company) { = company;

  public String getPhone() {
    return phone;

  public void setPhone(String phone) { = phone;

  public String getDesignated_shopper() {
    return designated_shopper;

  public void setDesignated_shopper(String designated_shopper) {
    this.designated_shopper = designated_shopper;

  public String getManager_id() {
    return manager_id;

  public void setManager_id(String manager_id) {
    this.manager_id = manager_id;

  public String getEmergency_contact_primary() {
    return emergency_contact_primary;

  public void setEmergency_contact_primary(String emergency_contact_primary) {
    this.emergency_contact_primary = emergency_contact_primary;

  public boolean isActive_directory_role() {
    return active_directory_role;

  public void setActive_directory_role(boolean active_directory_role) {
    this.active_directory_role = active_directory_role;

  public boolean isLotus_notes_mail_role() {
    return lotus_notes_mail_role;

  public void setLotus_notes_mail_role(boolean lotus_notes_mail_role) {
    this.lotus_notes_mail_role = lotus_notes_mail_role;

  public boolean isIs_doh_updated() {
    return is_doh_updated;

  public void setIs_doh_updated(boolean is_doh_updated) {
    this.is_doh_updated = is_doh_updated;

  public boolean isIs_dot_updated() {
    return is_dot_updated;

  public void setIs_dot_updated(boolean is_dot_updated) {
    this.is_dot_updated = is_dot_updated;

  public boolean isReports_to_me() {
    return reports_to_me;

  public void setReports_to_me(boolean reports_to_me) {
    this.reports_to_me = reports_to_me;

  public String toString() {
    return "Employee [id=" + id + ", dn=" + dn + ", uid=" + uid
        + ", birth_date=" + birth_date + ", isManager=" + isManager
        + ", employee_type=" + employee_type + ", status=" + status
        + ", termination_date=" + termination_date + ", title=" + title
        + ", first_name=" + first_name + ", last_name=" + last_name
        + ", department=" + department + ", location_code="
        + location_code + ", full_name=" + full_name + ", country="
        + country + ", company=" + company + ", phone=" + phone
        + ", manager_id=" + manager_id + ", designated_shopper="
        + designated_shopper + ", emergency_contact_primary="
        + emergency_contact_primary + ", active_directory_role="
        + active_directory_role + ", lotus_notes_mail_role="
        + lotus_notes_mail_role + ", is_doh_updated=" + is_doh_updated
        + ", is_dot_updated=" + is_dot_updated + ", reports_to_me="
        + reports_to_me + "]";

The View

<!DOCTYPE html>
    <title>Select Direct Reports</title>
    <link rel="STYLESHEET" type="text/css" href="include/dhtmlx.css">
    <script src="include/dhtmlx.js"></script>
    <div id="gridbox" style="width:1140px;height:700px;"></div> 
      function doOnChecked(row_id,cell_index,state) {
        console.log("Rows with id: " + row_id + " cell_index: " + cell_index + " state: " + state)
        if (state == true) {
          mygrid.cellById(row_id, 7).setValue("Daniel Houston");    // are you getting from session???
        } else {
          mygrid.cellById(row_id, 7).setValue("");
      mygrid = new dhtmlXGridObject('gridbox');
      mygrid.setHeader("UID,Name,Country,Store,Department,Title,Reports To Me,Manager Name");
      mygrid.attachEvent("onCheck", doOnChecked);
      mygrid.load("http://localhost:8080/SpringRestDhtmlxMongoDBExample/rest/employees", "js");

Web Deployment Descriptor (web.xml)

Our web.xml is quite straight forward. Here we define our DispatcherServlet servlet, define our servlet’s application context and define what our URL pattern is going to be for the dispatcher.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="" xmlns="" xsi:schemaLocation="" version="2.5">

Dispatcher Servlet Context (dispatcher-servlet.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns=""

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	<!-- Define the MongoTemplate which handles connectivity with MongoDB -->
	<beans:bean id="mongoTemplate" class="">
		<beans:constructor-arg name="mongo" ref="mongo" />
		<beans:constructor-arg name="databaseName" value="ldap" />
	<!-- Factory bean that creates the MongoDB instance -->
	<beans:bean id="mongo" class="">
    	<beans:property name="host" value="localhost"/>
	<!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes -->
	<beans:bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
	<context:component-scan base-package="com.avaldes" />

Root Context (root-context.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=""
	<!-- Root Context: defines shared resources visible to all other web components -->

Testing It Out

MongoDb Output

Output from our Spring MVC REST call /SpringRestDhtmlxMongoDBExample/rest/employees. DHTMLX supports two different flavors of JSON format. The Basic JSON Format and the Native JSON format.

Basic JSON Format

        { id:1001, data: ["Human Resources", "Alice Dwyane, false]},
        { id:2001, data: ["Systems Solutions", "Anne Smith", false]},
        { id:3001, data: ["Benefits Coordinator", "Anthony Firestone", true]}

Native JSON Format

{ "total_count":3, "pos":0, "data":[
        { "id": "1001", 
          "department" : "Human Resources", 
          "full_name" : "Alice Dwyane, 
          "reports_to_me" : false
        { "id": "2001", 
          "department" : "Systems Solutions", 
          "full_name" : "Anne Smith", 
          "reports_to_me" : false
        { "id": "3001", 
          "department" : "Benefits Coordinator", 
          "full_name" : "Anthony Firestone", 
          "reports_to_me" : true

The format displayed in the image screenshot below illustrates we are using the native JSON format supported by DHTMLX.

MongoDb Output

This output is from MongoDB which generates standard JSON format.

> db.employee.find()
{ "_id" : "ad1924", "dn" : "Employees", "uid" : "ad1924", "birthdate" : "01-01-1999", "isManager" : true, "employee_type" : "CORPORATE", "status" : "A", "termination_date" : "03-05-2015", "title" : "Sr. Recruiter", "first_name" : "Alice", "last_name" : "Dwayne", "department" : "Human Resources", "location_code" : 207, "full_name" : "Alice  Dwayne", "country" : "USA", "company" : "xxxy", "phone" : "888-555-1212", "designated_shopper" : "Tommy Dwayne", "emergency_contact_primary" : "Tommy Dwayne", "activeDirectoryRole" : false, "lotusNotesMailRole" : false, "isDohUpdated" : false, "isDotUpdated": false, "reportsToMe" : false }
{ "_id" : "ah0363", "dn" : "Employees", "uid" : "ah0363", "birthdate" : "01-01-1999", "isManager" : false, "status" : "A", "first_name" : "Anne", "last_name" : "Smith", "location_code" : 859, "full_name" : "Anne Smith", "company" : "xxxy", "phone" : "888-273-2092", "designated_shopper" : "Roslyn Smith", "emergency_contact_primary" : "Peter Smith", "activeDirectoryRole" : false, "lotusNotesMailRole" : false, "isDohUpdated" : false, "isDotUpdated": false, "reportsToMe" : false }
{ "_id" : "af4652", "dn" : "Employees", "uid" : "af4652", "birthdate" : "01-01-1999", "isManager" : false, "employee_type" : "CORPORATE", "status" : "A", "termination_date" : "22-01-2015", "title" : "Benefits Coordinator", "first_name" : "Anthony", "last_name" : "Firestone", "department" : "Human Resources", "location_code" : 777, "full_name" : "Anthony  Firestone", "country" : "USA", "company" : "bbby", "phone" : "758354314244", "designated_shopper" : "Victoria Firestone", "managerid" : "dh0132", "emergency_contact_primary" : "Edward Firestone", "activeDirectoryRole" : false, "lotusNotesMailRole" : false, "isDohUpdated" : false, "isDotUpdated" : false, "reportsToMe" : true }
{ "_id" : "dh0132", "dn" : "Employees", "uid" : "dh0132", "nationalid" : "1234567890", "birthdate" : "01-01-1999", "isManager" : true, "employee_type" : "CORPORATE", "status" : "A", "title" : "Senior Manager", "first_name" : "Daniel", "nickname" : "Dan", "last_name" : "Houston", "department" : "Acme Solutions", "location_code" : 345, "full_name" : "Daniel Houston", "country" : "USA", "company" : "xxxy", "alt_location" : "960", "mail" : "", "phone" : "888-234-5456", "managerid" : "dh0132", "activeDirectoryRole" : false, "lotusNotesMailRole" : true, "isDohUpdated" : false, "isDotUpdated" : false, "reportsToMe" : true }
{ "_id" : "ms0002", "dn" : "Employees", "uid" : "ms0002", "nationalid" : "1234567890", "birthdate" : "05-06-1988", "isManager" : false, "employee_type" : "CONSULTANT", "status" : "A", "hire_date" : "06-02-2015", "first_name" : "Mary", "nickname" : "mos", "last_name" : "Samuel", "department" : "Systems Technology", "full_name" : "Mary  Samuel", "country" : "Canada", "company" : "xxxy", "ConsultantCompany" : "IBM Global Services", "activeDirectoryRole" : false, "lotusNotesMailRole" : false, "isDohUpdated" : false, "isDotUpdated" : false, "reportsToMe" : false }
{ "_id" : "vs0004", "dn" : "Employees", "uid" : "vs0004", "nationalid" : "1234", "birthdate" : "03-06-1972", "isManager" : false, "employee_type" : "CORPORATE", "status" : "A", "hire_date" : "20-01-2015", "first_name" : "James", "last_name" : "Roberts", "department" : "Information Technology", "full_name" : "James Roberts", "country" : "United Kingdom", "company" : "xxxy", "managerid" : "dh0132", "activeDirectoryRole" : false, "lotusNotesMailRole" : false, "isDohUpdated" : false, "isDotUpdated" : false, "reportsToMe" : true }

Download the Code

That’s It!

I hope you enjoyed this tutorial. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

spring mvc dhtmlx

Related Spring Posts

  • Creating Hello World Application using Spring MVC on Eclipse IDE
    In this tutorial we will go into some detail on how to set up your Eclipse IDE environment so that you can develop Spring MVC projects. In this post, we will create our first Spring MVC project with the all to familiar “Hello World” sample program.
  • Spring MVC Form Handling Example
    The following tutorial will guide you on writing a simple web based application which makes use of forms using Spring Web MVC framework. With this web application you will be able to interact with the customer entry form and enter all of the required values and submit them to the backend processes. I have taken the liberty of using CSS to beautify and transform the HTML page from a standard drab look and feel to a more appealing view.
  • Spring @RequestHeader Annotation Example
    In this tutorial, we will discuss the different ways that Spring MVC allow us to access HTTP headers using annotation. We will discuss how to access individual header fields from the request object as well accessing all the headers by supplying Map and then iterating through the LinkedHashMap collection. We will also show you how to set the headers in the response object.
  • Spring MVC Exception Handling using @ExceptionHandler with AngularJS GUI
    Good exception handling is a essential part of any well developed Application Framework and Spring MVC is no exception — pardon the pun. Spring MVC provides several different ways to handle exceptions in our applications. In this tutorial, we will cover Controller Based Exception Handling using the @ExceptionHandler annotation above the method that will handle it.
  • Spring RESTful Web Service Example with JSON and Jackson using Spring Tool Suite
    For this example, I will be using Spring Tool Suite (STS) as it is the best integrated development environment for building the Spring framework projects. Spring is today's leading framework for building Java, Enterprise Edition (Java EE) applications. One additional feature that makes Spring MVC so appealing is that it now also supports REST (REpresentational State Transfer) for build Web Services.
  • Spring MVC RESTful Web Service Example with Spring Data for MongoDB and ExtJS GUI
    This post will show another example of how to build a RESTful web service using Spring MVC 4.0.6, Spring Data for MongoDB 1.6.1 so that we can integrate the web application with a highly efficient datastore (MongoDB 2.6). In this tutorial we will walk you through building the web service and NoSQL database backend and show you how to implement CRUD (Create, Read, Update and Delete) operations.
  • Building DHTMLX Grid Panel User Interface with Spring MVC Rest and MongoDB Backend
    In this tutorial we will show how easy it is to use DHTMLX dhtmlxGrid component while loading JSON data with Ajax pulling in data from the Spring MVC REST web service from our MongoDB data source. You will see how simple it is to create a visually appealing experience for your client(s) with minimal javascript coding.
  • Spring MVC with JNDI Datasource for DB2 on AS/400 using Tomcat
    In this tutorial we will discuss how to set up Spring MVC web services and configure a JNDI Datasource using Tomcat and connect to IBM DB2 Database on a AS/400. JNDI (Java Naming and Directory Interface) provides and interface to multiple naming and directory services.
  • Java Spring MVC Email Example using Apache Velocity
    In this tutorial we will discuss how to set up a Java Spring MVC RESTful Webservice with Email using Apache Velocity to create a Velocity template that is used to create an HTML email message and embed an image, as shown below, using MIME Multipart Message.
  • Implementing Basic and Advanced Search using Angular Material Design, Grid-UI, Spring MVC REST API and MongoDB Example
    In this tutorial we will discuss how to implement basic and advanced search techniques in MongoDB using AngularJS and Google’s Material Design with Spring MVC REST API backend. The advanced search user interface (UI) will use logical operators and build a JSON object which contains the search field name, boolean or logical operator and the search value.
  • Spring MVC Interceptor using HandlerInterceptorAdapter Example
    In this tutorial we will discuss how to use the HandlerInterceptorAdapter abstract class to create a Spring MVC interceptor. These interceptors are used to apply some type of processing to the requests either before, after or after the complete request has finished executing.

Please Share Us on Social Media


Leave a Reply

Your email address will not be published. Required fields are marked *