Over a million developers have joined DZone.

Mixing ExtJs, JSON-P and Java Web on NetBeans

· Java Zone

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.

In a previous article  I demonstrated how to build a ExtJs application. In the next lines I will show the content of a small patient management application using ExtJs as client-side framework and Java web with Spring framework in server-side.

I- Database schema table

Below the DDL script of the Patient table: 

CREATE TABLE Patient(
Id INT NOT NULL AUTO_INCREMENT,
FirstName VARCHAR(100) NOT NULL,
LastName  VARCHAR(100) NOT NULL, 
Address   VARCHAR(100) NOT NULL,
City      VARCHAR(100) NOT NULL,
Country   VARCHAR(100) NOT NULL,
PRIMARY KEY (ID)
);

II - Client-side : ExtJs  + MVC architecture

We need first to create a new Java Web project ( please, follow this tutorial ) with Spring Web MVC into NetBeans IDE.  Mine was named PatientManagement .

In the second time we create the client side using ExtJs framework and respecting MVC architecture ( Controller and View). Below the picture summarizing the project : 

The index.html file code source  :

<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<!DOCTYPE html>
<html>
    <head>
        <title>PATIENT MANAGEMENT</title>
        <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css">
        <script type="text/javascript" src="ext/ext-all.js"></script>
        <script type="text/javascript" src="app.js"></script>
    </head>
    <body></body>
</html>
The app.js  file content :
Ext.Loader.setConfig({
    enabled: true
});

Ext.application({
    name: 'PM',
    appFolder: 'front/app',
    controllers: ['PatientController'],
    autoCreateViewport: true,
    launch: function() {

    }
});

Views :

The AppToolbar.js file content :

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

Ext.define('PM.view.patient.AppToolbar', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.apptoolbar',    
    initComponent: function() {
        this.dockedItems = [
            {xtype: 'toolbar',
                dock: 'top',
                items: [
                    {
                        xtype: 'cycle',
                        showText: 'true',
                        text: '<html><b>Patient</b></html>',
                        width: '300',
                        menu: {
                            xtype: 'menu',
                            width: '150',
                            items: [
                                {
                                    xtype: 'menucheckitem',
                                    text: 'New patient',
                                    action: 'create'
                                },
                                {
                                    xtype: 'menucheckitem',
                                    text: 'Patients list',
                                    action: 'listing'
                                }

                            ]
                        }
                    }
                ]
            }

        ];

        this.callParent(arguments);
    }
});

The AddPatient.js file code source :

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */


Ext.define('PM.view.patient.AddPatient', {
    extend: 'Ext.window.Window',
    alias: 'widget.addpatient',
    title: 'Create a patient',
    layout: 'fit',
    autoShow: true,
    initComponent: function() {
        this.items = [
            {
                xtype: 'form',
                bodyStyle: {
                    background: 'none',
                    padding: '10px',
                    border: '0'
                },
                items: [
                    {
                        xtype: 'textfield',
                        name: 'firstname',
                        allowBlank: false,
                        fieldLabel: '<html><b>Firts Name</b></html>'
                    },
                    {
                        xtype: 'textfield',
                        name: 'lastname',
                        allowBlank: false,
                        fieldLabel: '<html><b>Last Name</b></html>'
                    },
                    {
                        xtype: 'textfield',
                        name: 'address',
                        fieldLabel: '<html><b>Address</b></html>',
                        allowBlank: false
                    },
                    {
                        xtype: 'textfield',
                        name: 'city',
                        fieldLabel: '<html><b>City</b></html>',
                        allowBlank: false
                    },
                    {
                        xtype: 'textfield',
                        name: 'country',
                        fieldLabel: '<html><b>Country</b></html>',
                        allowBlank: false

                    }
                ]
            }
        ];
        this.buttons = [
            {
                text: 'Save',
                action: 'save'
            },
            {
                text: 'Cancel',
                scope: this,
                handler: this.close
            }
        ];

        this.callParent(arguments);
    }
});
The viewport  Viewport.js file content :
Ext.define('PM.view.Viewport', {
    extend: 'Ext.container.Viewport',
    alias: 'widget.viewport',    
    items: [
        {
            xtype: 'apptoolbar'
        }],
    initComponent: function() {
       this.callParent(arguments);
    }
}); 

Controller :

The content of PatientController.js is below :

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */


Ext.define('PM.controller.PatientController', {
    extend: 'Ext.app.Controller',
    views: ['patient.AddPatient', 'patient.AppToolbar'],
    init: function() {
        this.control({
            'addpatient button[action=save]': {
                click: this.doCreatePatient
            },
            'apptoolbar > toolbar > cycle > menu > menucheckitem[action=create]': {
                click: this.onCreatePatient
            }

        });
    },
    onCreatePatient: function() {
        //The panel to create a patient appears on the screen
        var view = Ext.widget('addpatient');
    },
    //Function to create a new patient
    doCreatePatient: function(button) {
        var win = button.up('window'),
                form = win.down('form'),
                values = form.getValues()
        if (form.getForm().isValid()) {
            Ext.Ajax.request({
                url: 'PatientController',
                method: 'POST',
                params: {
                    patientcreateData: Ext.encode(values)
                },
                scope: this,
                stateful: true
            });

            win.close();
        }
    },
});

In this controller we use the singleton Ext.Ajax  to send an HTTP request to a remote server. In our example we will use the method POST to send the data and we will use the server-side servlet  PatientController.java (see below the code source).  The JSON object is patientcreateData.

The web.xml file has been modified according the project to have index.html file as welcome page.

<welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

III - Server-side implementation

Below the sample of Java files defining the server-side of the application :

The model  Patient.java  code is here:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.model.patientmanagement;

/**
 *
 * @author constantin
 */
public class Patient {

    private int id;
    private String firstname;
    private String lastname;
    private String address;
    private String city;
    private String country;

    public Patient() {
    }

    public Patient(String firstname, String lastname, String address, String city, String country) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.address = address;
        this.city = city;
        this.country = country;
    }

    public int getId() {
        return id;
    }

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

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

}

The DAO PatientDao.java file content is here :

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.dao.patientmanagement;

import com.model.patientmanagement.Patient;
import java.util.List;
import javax.sql.DataSource;

/**
 *
 * @author constantin
 */
public interface PatientDao {

    public void setDataSource(DataSource dataSource);

    public void createPatient(String firstname, String lastname, String address, String city, String country);

    public Patient getPatientById(Integer id);

    public void deletePatient(Integer id);

    public List<Patient> listPatients();

    public void updateFirstName(Integer id, String firstname);

}

The PatientTemplate.java source :

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.impl.patientmanagement;

import com.dao.patientmanagement.PatientDao;
import com.model.patientmanagement.Patient;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 *
 * @author constantin
 */
public class PatientTemplate implements PatientDao {

    private DataSource dataSource;
    private JdbcTemplate jdbcTemplateObject;

    @Override
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplateObject = new JdbcTemplate(dataSource);
    }

    @Override
    public void createPatient(String firstname, String lastname, String address, String city, String country) {
        try {
            String Sql = "insert into Patient(firstname, lastname, address, city,country) values (?,?,?,?,?)";
            jdbcTemplateObject.update(Sql, firstname, lastname, address, city, country);

        } catch (DataAccessException ex) {
            System.out.println("Error" + ex.getMessage());
        }
    }

    @Override
    public Patient getPatientById(Integer id) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void deletePatient(Integer id) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public List<Patient> listPatients() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void updateFirstName(Integer id, String firstname) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}

The PatientMapper.java file content is:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.impl.patientmanagement;

import com.model.patientmanagement.Patient;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

/**
 *
 * @author constantin
 */
public class PatientMapper implements RowMapper<Patient> {

    @Override
    public Patient mapRow(ResultSet rs, int i) throws SQLException {
        //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        Patient patient = new Patient(); 
        patient.setId(rs.getInt("id"));
        patient.setFirstname(rs.getString("firstname"));
        patient.setLastname(rs.getString("lastname"));
        patient.setAddress(rs.getString("address"));
        patient.setCity(rs.getString("city"));
        patient.setCountry(rs.getString("country"));  
        return patient ;  
    }
}

Here the doPost method code source of the servlet PatientController.java :

 @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
      
        //Get the context of the application
        ServletContext servletContext = this.getServletContext();

        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

        String patientcreateData = request.getParameter("patientcreateData");

        //I parse here the json object
        GenericJsonParser jsonPatient = new GenericJsonParser();
        HashMap<String, String> patientMap = jsonPatient.getJsonMap(patientcreateData);

        String firstname = patientMap.get("firstname");
        String lastname = patientMap.get("lastname");
        String address = patientMap.get("address");
        String city = patientMap.get("city");
        String country = patientMap.get("country");

        PatientTemplate patient = (PatientTemplate) wac.getBean("patienttemplate");
        
        patient.createPatient(firstname, lastname, address, city, country);               

    }

The class to parse Json object is implemented as shown below  (GenericJsonParser.java):

This class is very important since there is no method in JSON-P API to bind Java object and JSON object. It parses the Json object a return a map that is better easy to be used in Java code.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.controller.patientmanagement;

import java.io.StringReader;
import java.util.HashMap;
import javax.json.Json;
import javax.json.stream.JsonParser;
import static javax.json.stream.JsonParser.Event.END_OBJECT;
import static javax.json.stream.JsonParser.Event.KEY_NAME;

/**
 *
 * @author constantin Drabo
 * This class allow you to parse a  Json object coming from client side
 */
public class GenericJsonParser {

    public GenericJsonParser() {
    }

    public HashMap<String, String> getJsonMap(String jsonflux) {

        String keyvalue;
        JsonParser parser = Json.createParser(new StringReader(jsonflux));
        JsonParser.Event event = parser.next();

        HashMap<String, String> jsonElements;
        jsonElements = new HashMap<String, String>();

        while (event != END_OBJECT) {
            event = parser.next();
            if (event == KEY_NAME) {
                keyvalue = parser.getString();
                System.out.println("KeyValue === " + keyvalue);
                parser.next();
                jsonElements.put(keyvalue, parser.getString());
            }
        }

        return jsonElements;
    }

}


IV- Run the application

The application will look like this when it is running :

Here a sample data we will save :

When  they click on the button Save they obtain this Json object (here captured by Firebug ) :

The Java Zone is brought to you in partnership with JetBrains.  Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience.

Topics:

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}