Skip to main content

Consuming a REST service within JSF using JQuery and Handlebars [THE TRUE MVC APPROACH]

Posted by lamine_ba on July 29, 2012 at 3:13 PM PDT

The indispensable first step to getting the things you want out of life is this : decide what you want.
Ben Stein

INTRODUCTION

Ladies and Gentlemen, assuredly the chances for a technology to fall are huge if it is not driven by a real vision. And in my own perception, a technology is like a pattern, so without a constant transformation, it cannot live beyond the context in which it was made. And frankly, does one of you see any glory in taking a GUI pattern like MVC and to apply it blindly on the web? For sure, if not done carefully, it would just lead to such question : "OK now, how are we going to make our web framework stateless?". But the solution of a problem does always lie in its cause.

Consuming a REST service using JQuery

Ladies and Gentlemen, the aim of this post is to show you, how to consume a RESTful web service within a JSF application. And for that, we will use today a JavaScript library like JQuery and a client-side templating system like Handlebars which itself is derived from another one called Mustache. And with your permission, I'm going now and from a web developer perspective to lay down things by building the REST API and that in a total disconnection with any of its target clients.

Model

  1. @XmlAccessorType(XmlAccessType.NONE)
  2. @XmlRootElement
  3. class Customer {
  4.  
  5.   @XmlElement Long id
  6.   @XmlElement String firstName
  7.   @XmlElement String lastName
  8.  
  9. }

Controller

  1. @Path("/customers")
  2. class CustomerService {
  3.        
  4.         @GET
  5.         @Produces([MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML])
  6.         def List<Customer> getCustomers() {
  7.             dao.customers
  8.         }
  9. }

And once it is done and from a web designer perspective, I'm going now to design the Facelets page and to reference in it, the JavaScript libraries needed to send an ajax request to the service and to render the data on the client-side.

View [index.xhtml]

  1. <!DOCTYPE html>
  2. <html  xmlns:h="http://java.sun.com/jsf/html">
  3.  
  4. <h:head>
  5.         <h:outputScript library="js" name="handlebars-1.0.0.beta.6.js"/>
  6.         <h:outputScript library="js" name="jquery.js"/>
  7.         <h:outputScript library="js" name="module.js"/>
  8. </h:head>
  9.                
  10. <body>
  11.  
  12.   <table>
  13.         <thead>
  14.            <tr>
  15.              <th>ID</th>
  16.              <th>First Name</th>
  17.              <th>Last Name</th>
  18.           </tr>
  19.         </thead>
  20.         <tbody>
  21.            <script id="template" type="text/x-handlebars-template">
  22.                  {{#each customer}}
  23.                    <tr>
  24.                      <td>{{id}}</td>
  25.                      <td>{{firstName}}</td>
  26.                      <td>{{lastName}}</td>
  27.                    </tr>
  28.                  {{/each}}
  29.           </script>
  30.         </tbody>
  31.  </table>
  32.  
  33. </body>
  34.        
  35.  </html>        
  36.              

JavaScript [module.js]

  1. var table={    
  2.        
  3.     display:function(url){
  4.         $.ajax({
  5.             type:"GET",
  6.             url:url,
  7.             dataType:"json",
  8.             success:function(data) {
  9.                 var template = $("#template").html();
  10.                 var render = Handlebars.compile(template);
  11.                 $("tbody").append(render(data));
  12.             }
  13.         });
  14.      }
  15.  
  16. };
  17.  
  18. $(function(){
  19.         table.display("/customers");
  20. });

Output

Component [ table.xhtml ]

  1. <html xmlns:cc="http://java.sun.com/jsf/composite">
  2.  
  3. <cc:interface>
  4.         <cc:attribute name="url"/>    
  5. </cc:interface>
  6.  
  7. <cc:implementation>
  8.  
  9.         <table  url="#{cc.attrs.url}">
  10.             <script id="template" type="text/x-handlebars-template">
  11.                 <cc:insertChildren/>
  12.             </script>
  13.         </table>
  14.        
  15. </cc:implementation>
  16.  
  17. </html>

View [ index.xhtml ]

  1. <html   xmlns:h="http://java.sun.com/jsf/html"
  2.       xmlns:c="http://java.sun.com/jsf/composite/components">
  3.                
  4.         <body>
  5.  
  6.            <c:table url="/customers">
  7.                <thead>
  8.                   <tr>
  9.                       <th>ID</th>
  10.                       <th>First Name</th>
  11.                       <th>Last Name</th>
  12.                    </tr>
  13.                 </thead>
  14.                 <tbody>
  15.                     {{#each customer}}
  16.                       <tr>
  17.                         <td>{{id}}</td>
  18.                         <td>{{firstName}}</td>
  19.                         <td>{{lastName}}</td>
  20.                      </tr>
  21.                     {{/each}}
  22.                 </tbody>
  23.            </c:table>
  24.                
  25.         </body>
  26.        
  27.  </html>



twitter : lamine_ba

 

AttachmentSize
customers-api.png7 KB
module-directory.png4.19 KB
customers-render.PNG3.21 KB
module-directory-2.png5.13 KB