DWR, Hibernate and Dojo.E - A Tutorial

34
Direct Web Remoting, Direct Web Remoting, Hibernate and Dojo.E Hibernate and Dojo.E “Easy Ajax for Java” Joel Barciauskas October 3, 2008

description

This tutorial will walk you through the steps of creating a simple database-driven AJAX application using Direct Web Remoting (DWR) 2.0, Hibernate 3.0 and a new open source project from Nexaweb Technologies, dojo.E. dojo.E is an extensible markup processing engine that out-of-the-box will translate XML into dojo components.

Transcript of DWR, Hibernate and Dojo.E - A Tutorial

Page 1: DWR, Hibernate and Dojo.E - A Tutorial

Direct Web Remoting, Direct Web Remoting, Hibernate and Dojo.EHibernate and Dojo.E

“Easy Ajax for Java”

Joel Barciauskas

October 3, 2008

Page 2: DWR, Hibernate and Dojo.E - A Tutorial

What is DWR?

• “Easy Ajax for Java” implies two parts

– Server – Java servlet

– Client – JavaScript auto-generated by the Java servlet

• Enables JSON to JavaBean serialization

• Exposes selected methods and JavaBean properties on the server as client-side JavaScript methods and objects

• Reverse Ajax – IMB-like functionality

Page 3: DWR, Hibernate and Dojo.E - A Tutorial

Why use DWR? Why not?

• Pros

– Avoid replication of effort defining model objects on both server and client

– No XHR boilerplate required

– No serialization boilerplate

– JSON is fastest format to serialize/deserialize in the browser

• Cons

– Less control over network requests

E.g., harder to bundle requests

– Not RESTful, all requests processed through POST data rather than URLs

Best for single-page applications

Page 4: DWR, Hibernate and Dojo.E - A Tutorial

Let’s see it

• Application: Simple database create and read

• Using: JavaScript, DWR 2.0, Hibernate 3.0, Derby

• Shell: http://source.nexaweb.com/svn/repos/trunk/tutorials/ajax/DWRExample/

Page 5: DWR, Hibernate and Dojo.E - A Tutorial

Create your domain class (JavaBean)• src/events/Event.java

package events;

import java.util.Date;

public class Event {

private Long id;

private String title;

private Date date;

public Event() {}

public Long getId() { return id; }

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

public Date getDate() { return date; }

public void setDate(Date date) { this.date = date; }

public String getTitle() { return title; }

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

}

Page 6: DWR, Hibernate and Dojo.E - A Tutorial

Create Hibernate XML Mapping

• src/events/Event.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="events.Event" table="EVENTS"> </class>

</hibernate-mapping>

Page 7: DWR, Hibernate and Dojo.E - A Tutorial

Add Property Mappings• src/events/Event.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="events.Event" table="EVENTS">

<id name="id" column="EVENT_ID">

<generator class="native"/>

</id>

<property name="date" type="timestamp" column="EVENT_DATE"/>

<property name="title"/>

</class>

</hibernate-mapping>

Page 8: DWR, Hibernate and Dojo.E - A Tutorial

Create Hibernate Configuration• src/hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration> <session-factory>

<!-- Database connection settings -->

<property name="connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property>

<property name="connection.url“>jdbc:derby:eventDB;create=true</property>

<!-- JDBC connection pool (use the built-in) -->

<property name="connection.pool_size">1</property>

<!-- SQL dialect -->

<property name="dialect">org.hibernate.dialect.DerbyDialect</property>

<!-- Enable Hibernate's automatic session context management -->

<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->

<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->

<property name="hbm2ddl.auto">create</property>

<mapping resource="events/Event.hbm.xml"/>

</session-factory>

</hibernate-configuration>

Page 9: DWR, Hibernate and Dojo.E - A Tutorial

Create SessionFactory instance• src/util/HibernateUtil.java

package util;

import org.hibernate.*;

import org.hibernate.cfg.*;

public class HibernateUtil {

private static final SessionFactory sessionFactory;

static {

try { // Create the SessionFactory from hibernate.cfg.xml

sessionFactory = new Configuration().configure().buildSessionFactory();

} catch (Throwable ex) {

// Make sure you log the exception, as it might be swallowed

System.err.println("Initial SessionFactory creation failed." + ex);

throw new ExceptionInInitializerError(ex);

}

}

public static SessionFactory getSessionFactory() { return sessionFactory; }

}

Note: This can also be achieved through the Spring integration – “use the Spring OpenSessionInViewFilter which will ensure that a Hibernate Session is open” (http://directwebremoting.org/dwr/server/hibernate)

Page 10: DWR, Hibernate and Dojo.E - A Tutorial

Create an Event Manager• src/events/EventManager.java

package events;

import org.hibernate.Session;

import java.util.Date;

import java.util.List;

import util.HibernateUtil;

public class EventManager {

public void createAndStoreEvent(String title, Date theDate) {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

Event theEvent = new Event();

theEvent.setTitle(title);

theEvent.setDate(theDate);

session.save(theEvent);

session.getTransaction().commit();

}

public List listEvents() {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

List result = session.createQuery("from Event").list();

session.getTransaction().commit();

return result;

}

}

Page 11: DWR, Hibernate and Dojo.E - A Tutorial

Add the DWR servlet to web.xml• WebContent/WEB-INF/web.xml

<servlet>

<servlet-name>dwr-invoker</servlet-name>

<display-name>DWR Servlet</display-name>

<servlet-class>

org.directwebremoting.servlet.DwrServlet

</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>dwr-invoker</servlet-name>

<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

Page 12: DWR, Hibernate and Dojo.E - A Tutorial

Create a Remote Proxy and Expose Remote Methods

• Src/events/EventManager.java

package events;

import org.directwebremoting.annotations.RemoteMethod;

import org.directwebremoting.annotations.RemoteProxy;

import org.hibernate.Session;

import java.util.Date;

import java.util.List;

import util.HibernateUtil;

@RemoteProxy

public class EventManager {

@RemoteMethod

public void createAndStoreEvent(String title, String theDate) {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

Event theEvent = new Event();

theEvent.setTitle(title);

theEvent.setDateString(theDate);

session.save(theEvent);

session.getTransaction().commit();

}

@RemoteMethod

public List listEvents() {

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction();

List result = session.createQuery("from Event").list();

session.getTransaction().commit();

return result;

}

}

Page 13: DWR, Hibernate and Dojo.E - A Tutorial

Annotate Event as a Data Transfer Object• src/events/Event.java

package events;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import org.directwebremoting.annotations.DataTransferObject;

import org.directwebremoting.annotations.RemoteProperty;

@DataTransferObject

public class Event {

@RemoteProperty

private Long id;

@RemoteProperty

private String title;

private Date date;

public Event() {}

public Long getId() {

return id;

}

private void setId(Long id) {

this.id = id;

}

@RemoteProperty

public String getDateString() {

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

return sdf.format(this.date);

}

[continued on next slide]

Page 14: DWR, Hibernate and Dojo.E - A Tutorial

Annotate Event as a Data Transfer Object (con’t)• src/events/Event.java [continued]

@RemoteProperty

public void setDateString(String dateStr) {

SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

try {

this.date = sdf.parse(dateStr);

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public Date getDate() {

return date;

}

public void setDate(Date date) {

this.date = date;

}

}

Note: We added getDateString and setDateString here, because there is no implicit conversion available between JavaScript dates and Java dates – mostly arrays, strings, BigNumber, and primitives. See http://directwebremoting.org/dwr/server/dwrxml/converters for more information.

Page 15: DWR, Hibernate and Dojo.E - A Tutorial

Update web.xml• WebContent/WEB-INF/web.xml

<servlet>

<servlet-name>dwr-invoker</servlet-name>

<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>

<init-param>

<param-name>classes</param-name>

<param-value>

events.Event,

events.EventManager

</param-value>

</init-param>

<init-param>

<param-name>debug</param-name>

<param-value>true</param-value>

</init-param>

</servlet>

Page 16: DWR, Hibernate and Dojo.E - A Tutorial

Using DWR Debug Mode

• Go to http://localhost:8080/DWRExample/dwr/

– Click “EventManager”

– Enter “Event 1” in the first parameter of createAndStoreEvent

– Enter “10/01/2008” in the second parameter

• Click the Execute button

Page 17: DWR, Hibernate and Dojo.E - A Tutorial
Page 18: DWR, Hibernate and Dojo.E - A Tutorial

• Click the Execute button next to listEvents()

Page 19: DWR, Hibernate and Dojo.E - A Tutorial

Let’s add DWR on the client side

• File->New->Web->HTML-> WebContent/index.html

• Open and edit title “DWR Example”

• Go back to http://localhost:8080/DWRExample/dwr/test/EventManager and copy and paste the script tags

Page 20: DWR, Hibernate and Dojo.E - A Tutorial

More Dojo boilerplate• Paste the following too:

<script type="text/javascript" src="js/dojo/dojo/dojo.js"

djConfig="isDebug: true, parseOnLoad: true"></script>

<link rel="stylesheet" type="text/css"

href="js/dojo/dojo/resources/dojo.css" />

<link rel="stylesheet" type="text/css"

href="js/dojo/dijit/themes/tundra/tundra.css" />

<link rel="stylesheet" type="text/css"

href="js/dojo/dojox/grid/_grid/Grid.css" />

<link rel="stylesheet" type="text/css"

href="js/dojo/dojox/grid/_grid/tundraGrid.css" />

<script type="text/javascript">

dojo.require("dijit.form.Button");

dojo.require("dijit.form.TextBox");

dojo.require("dijit.form.DateTextBox");

dojo.require("dojox.grid.Grid");

dojo.require("dojo.data.ItemFileReadStore");

dojo.require("dojoe.dojoe");

</script>

Page 21: DWR, Hibernate and Dojo.E - A Tutorial

Add Dojo.E

• Add tundra class to body tag:

<body class="tundra">

• Create XML file WebContent/dwrDojoE.xml

• And add tag

<script type="text/xml" dojoType="dojoe.XmlScript" src="dwrDojoE.xml"></script>

Page 22: DWR, Hibernate and Dojo.E - A Tutorial

Edit Dojo.E

• WebContent/dwrDojoE.xml

<ui xmlns="html" xmlns:dijit="dijit" xmlns:dojox="dojox">

<dijit:form.Button>

Refresh

</dijit:form.Button>

<dojox:grid.Grid id="gridNode" jsId="grid" elasticView="0" style="height:300px; width:500px"/>

</ui>

Page 23: DWR, Hibernate and Dojo.E - A Tutorial

Where’s the Grid?!?

Page 24: DWR, Hibernate and Dojo.E - A Tutorial

Create a grid layout• WebContent/index.html

<body class="tundra">'

<script type="text/javascript">

var layout = [{

cells: [[

{

name: 'Event ID',

field: 'id',

width: 'auto'

},

{

name: 'Date',

field: 'dateString',

width: 'auto'

}, {

name: 'Event',

field: 'title',

width: 'auto'

}]]

}];

</script>

Note the correlation between the field values above and the RemoteProperty defintions of Event.java

Page 25: DWR, Hibernate and Dojo.E - A Tutorial

Add the layout to the Grid

• WebContent/dwrDojoE.xml

<ui >

<dijit:form.Button>

Refresh

</dijit:form.Button>

<dojox:grid.Grid id="gridNode"

structure=“layout”

jsId="grid" elasticView="0" style="height:300px; width:500px"/>

</ui>

Page 26: DWR, Hibernate and Dojo.E - A Tutorial

Now let’s get some data• WebContent/index.html

var putEvents = function(list){

var dataStore = new Array;

dataStore["items"] = list;

dataStore["label"] = "title";

var model = new dojox.grid.data.DojoData(null, null, {

jsId: 'model',

store: new dojo.data.ItemFileReadStore({

data: dataStore

}),

query: {

title: '*'

}

});

grid.setModel(model);

grid.refresh();

grid.render();

};

Page 27: DWR, Hibernate and Dojo.E - A Tutorial

Update Dojo.E

• WebContent/dwrDojoE.xml

<ui>

<dijit:form.Button onClick="EventManager.listEvents(putEvents)">

Refresh

</dijit:form.Button>

<dojox:grid.Grid id="gridNode" jsId="grid" elasticView="0" style="height:300px; width:500px"/>

</ui>

Page 28: DWR, Hibernate and Dojo.E - A Tutorial

Click Refresh

Page 29: DWR, Hibernate and Dojo.E - A Tutorial

Create a method to create an event• WebContent/index.html

var createEvent = function(titleId, dateId){

var title = dojo.byId(titleId).value;

var date = dojo.byId(dateId).value;

EventManager.createAndStoreEvent(title, date);

EventManager.listEvents(putEvents);

};

Page 30: DWR, Hibernate and Dojo.E - A Tutorial

Let’s Add Input Controls• WebContent/dwrDojoE.xml

<ui >

<dijit:form.Button onClick="EventManager.listEvents(putEvents)">

Refresh

</dijit:form.Button>

<dojox:grid.Grid id="gridNode" jsId="grid" structure="layout" elasticView="0“

style="height:300px; width:500px"/>

<label for="eventTitle" style="float: left;">Event Title:</label>

<dijit:form.TextBox style="float: left;" id="eventTitle" value=""/>

<label for="eventDate" style="float: left;">Event Date:</label>

<dijit:form.DateTextBox id="eventDate" value="" style="float: left;"/>

<dijit:form.Button style="float: left;“

onclick="createEvent('eventTitle', 'eventDate')" label="Add Event">

</dijit:form.Button>

</ui>

Page 31: DWR, Hibernate and Dojo.E - A Tutorial

Reload the page

Page 32: DWR, Hibernate and Dojo.E - A Tutorial

Enter a title and date

Page 33: DWR, Hibernate and Dojo.E - A Tutorial

Load data at startup

• WebContent/index.html

dojo.addOnLoad(function() {

EventManager.listEvents(putEvents);

});

Page 34: DWR, Hibernate and Dojo.E - A Tutorial

Final note

• If using more complex object models with Hibernate, use the HibernateBeanConverter3 – See http://directwebremoting.org/dwr/server/hibernate