1 / 34

Direct Web Remoting, Hibernate and Dojo.E

Direct Web Remoting, Hibernate and Dojo.E. “Easy Ajax for Java” Joel Barciauskas October 3, 2008. 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

nate
Télécharger la présentation

Direct Web Remoting, Hibernate and Dojo.E

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. 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

  3. 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

  4. 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/

  5. 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; } }

  6. 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>

  7. 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>

  8. 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>

  9. 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)

  10. 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; } }

  11. 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>

  12. 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; } }

  13. 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]

  14. 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.

  15. 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>

  16. 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

  17. Click the Execute button next to listEvents()

  18. 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

  19. 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>

  20. 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>

  21. 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>

  22. Where’s the Grid?!?

  23. 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

  24. 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>

  25. 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(); };

  26. 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>

  27. Click Refresh

  28. 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); };

  29. 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>

  30. Reload the page

  31. Enter a title and date

  32. Load data at startup • WebContent/index.html dojo.addOnLoad(function() { EventManager.listEvents(putEvents); });

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

More Related