Spring Data provides you several ways of consuming the REST repositories through a JavaScript frameworks. We have already provided a set of tutorials that discussed about using Spring Data REST with jQuery, AngularJS, Backbone.js and Rest.js. For this tutorial we’re going to explain you how could Sencha Touch be integrated for accessing the services.
Sencha Touch, a high-performance HTML5 mobile application framework, is the cornerstone of the Sencha HTML5 platform. Built for enabling world-class user experiences, Sencha Touch is the only framework that enables developers to build powerful apps that work on iOS, Android, BlackBerry, Windows Phone, and more.
Our goal of introducing this tutorial isn’t going deep into discussing the Sencha Touch framework, but it’s simply a normal sample adhered the Sencha Touch Model, View & Store modules.
In this tutorial, a gemfire MessageRepository will be exported using the REST exporter, as the GemFireBean will populate a dummy message into gemfire in-memory cache. A Sencha Touch framework components will be contribute each other for consuming the populated messages. Let’s see how could implement that scenario, meanwhile you can contribute us by leave your comments in the below comments section.
1. Project Structure
When it comes to implement a Sencha Touch modules, you have to follow the below structure at least for those files related to the Sencha itself. So, be sure that your model, view and store JavaScript files are located under app folder followed by the type of the module. Look at the structure.
As you’ve noted, MessageModel, MessageStore and MessageView are located under folders represents their type. The exception there, is the MessageApplication which referenced by the index.html and by that it could be located anywhere you want.
2. Tools Used
- JDK 1.6. Apache Tomcat 7.
- GemFire 7.0.1 Platform (JAR distribution)
- Maven 3.
- Tomcat 7.
- Sencha Touch
- Spring Data
- Spring Framework
3. Persistent Entities
We have a Message entity or object that needs to be used for the Restful service. This is the primary entity class for this tutorial. Nothing new here, a Message entity will be the only entity where the persistent store is a gemfire.
Message.java
package net.javabeat.springdata.data; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.gemfire.mapping.Region; @Region("messages") public class Message { @Id private String messageId; private String message; public Message() { } @PersistenceConstructor public Message(String id, String message) { this.messageId = id; this.message = message; } public String getMessageId() { return messageId; } public void setMessageId(String messageId) { this.messageId = messageId; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
4. Spring Data Repository
Repository provides you an abstraction layer in which you have never been providing an implementation for your CRUD operations even if it was a small portion of code. What you should have to do is to create your own interface that extends the Spring Data’s special Repository and the remaining work has been left for the Spring framework to complete the required implementation. So, you should have to provide a repository like below. If you look at the below class MessageRepository, it extends the CrudeRepository which is the spring data’s interface which defines the methods for the CRUD operations.
MessageRepository.java
package net.javabeat.springdata.repo; import net.javabeat.springdata.data.Message; import org.springframework.data.repository.CrudRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(collectionResourceRel="messages",path="messages") public interface MessageRepository extends CrudRepository<Message,Integer> {}
5. Spring Service
The main goal of implementing such a service is to allow the application populating a dummy message into gemfire in-memory cache. @Autowired is used for annotating the setMessageRepository and that implementation gives you the ability to inject/wired the repository proxy by using the setter rather than the field itself. That’s type of injection allows you to add whatever you want of business logic. To serve our purpose, we add the needed code for populating the message into gemfire cache.
GemFireBean.java
package net.javabeat.springdata.bean; import net.javabeat.springdata.data.Message; import net.javabeat.springdata.repo.MessageRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class GemFireBean { MessageRepository messageRepository; public GemFireBean(){ } public MessageRepository getMessageRepository() { return messageRepository; } @Autowired public void setMessageRepository(MessageRepository messageRepository) { // Message repository has been set this.messageRepository = messageRepository; // Add some messages into GemFire for being seen Message message = new Message(); message.setMessageId("1"); message.setMessage("Spring Data REST resources can be consumed by different JavaScript framework \n One of the most important framework here is Sencha Touch"); messageRepository.save(message); } }
6. Spring Configurations
This is the simple XML configuration for the spring beans.
SpringContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire" xmlns:gfe="http://www.springframework.org/schema/gemfire" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd"> <!-- Search for spring components --> <context:component-scan base-package="net.javabeat"></context:component-scan> <!-- Declare GemFire Cache --> <gfe:cache/> <!-- Local region for being used by the Message --> <gfe:local-region id="messages" value-constraint="net.javabeat.springdata.data.Message"/> <!-- Search for GemFire repositories --> <gfe-data:repositories base-package="net.javabeat.springdata.repo"/> </beans>
7. Repository Rest Dispatcher Servlet & Web deployment Descriptor
To install spring data rest alongside your existing web application, you need to include the appropriate configuration.
- Spring Data REST configuration is defined in a class called RepositoryRestMvcConfiguration.
- Since Spring Data REST is simply a spring MVC application, you only need to include the RepositoryRestDispatcherServlet to use the REST functionality when we use spring framework with XML configurations.
The web deployment descriptor seems like below.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" metadata-complete="true" version="2.5"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-config/SpringContext.xml</param-value> </context-param> <servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.data.rest.webmvc.RepositoryRestDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
8. Expose GemFire Repositories Directly
It’s just a steps for exposing the GemFire repositories through using of google Dev HTTP. For doing that just follow the below steps:
- Open Google Chrome Http Dev.
- Type your host followed by the port number followed with the web context for the deployed application which should results in the token http://localhost:8080/SpringData-GemFire-SenchaTouch-1.0.
- For consuming the messages resources, you have to add the RepositoryRestDispactherServlet mapping url which mentioned in the web.xml and it’s /rest/ which results in url value like http://localhost:8080/SpringData-GemFire-REST-SenchaTouch-1.0/rest/
- Add the The path segment under which this resource is to be exported. that value was provided using the path property at the header of the MessageRepository in order to be able of exposing the messages resource like below.
9. Implement Sencha Touch Modules
To implement the Sencha Touch Modules you have to follow the below steps:
- Create a model by developing an Ext model named MessageModel. Place this model in the app/model directory. This is the default location for Sencha Touch models and will allow Sencha’s loader to find it. MessageModel extends Ext.data.Model and defines two fields: message and href.
MessageModel.js
Ext.define('JavaBeat.model.MessageModel', { extend: 'Ext.data.Model', config: { fields: [ { name:'message', name:'href' } ] } });
- Create a view by using Sencha’s Ext.Panel can be used as a simple view. This file should also be placed in Sencha’s default location for views /app/view. The contents of the view are defined by the template described in the tpl config option. Those braced tokens (i.e. {message}) will be replaced by the model fields when the view is rendered.
MessageView.js
Ext.define('JavaBeat.view.MessageView', { extend: 'Ext.Panel', config: { fullscreen: true, tpl:'<p>Message #1 :: {message} :: <a href='+"{href}"+'>Message Link</a></p>' } });
- Next, create an Ext store that will load the model. The store extends Ext.data.store and references our MessageModel. To instruct the store to use REST proxy, we configure it with a proxy definition object with type:”rest” and then point it at our REST endpoint url.
MessageStore.js
Ext.define('JavaBeat.store.MessagesStore', { extend: 'Ext.data.Store', config: { model: 'JavaBeat.model.MessageModel', proxy: { type: 'rest', url: 'http://localhost:8080/SpringData-GemFire-REST-SenchaTouch-1.0/rest/messages' } } });
- Next, create an Ext.application object using Sencha’s Ext.application shortcut function. The application object automatically resolves the location of the models, views, and stores if you follow Sencha’s default directory convention as we’ve mentioned above. You must also specify the model, view and store in the models, views, and stores arrays so that Sencha’s loader can find and fetch those files. Adding a launch callback so that the application will be composed after all files have loaded. Inside this callback, create an instance of the view and an instance of the store. Configure the store to autoload so it will immediately fetch the model at the endpoint url. After that, you have to add a load listener to move the fetched data into the view. As you’ve seen, some additional instructions that have been added for manipulating the response to be stored inside array of messages.
MessageApplication.js
Ext.application({ name: 'JavaBeat', models: [ 'MessageModel' ], stores: [ 'MessagesStore' ], views: [ 'MessageView' ], launch: function () { var view = Ext.create('JavaBeat.view.MessageView', {}); Ext.create('JavaBeat.store.MessagesStore', { autoLoad: true, listeners: { load: function (self, records) { // Filling Array of messages var arr = []; for(m in records[0].raw._embedded.messages){ var message = { message: records[0].raw._embedded.messages[m].message, href:records[0].raw._embedded.messages[m]._links.self.href }; arr.push(message); } view.setData(arr[0]); } } }); } }); Ext.Loader.setConfig({ disableCaching: false });
10. HTML View
It’s just the HTML page where Sencha’s library (Sencha’s CDN) has been loaded and the Sencha’s MessageApplication.js (Application Object) has been referenced.
index.html
<html> <head> <title>JavaBeat Tutorial</title> <script src="//cdn.sencha.io/touch/sencha-touch-2.1.1/sencha-touch-all.js"></script> <script src="MessageApplication.js"></script> </head> <body> <h2>JavaBeat Tutorial</h2> <h3>Spring Data REST - <h3> <h3>Consuming GemFire REST Resources Using Sencha Touch</h3> </body> </html>
11. Maven Build
It’s the file that responsible of collecting the dependencies required for the current application.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.javabeat.springdata</groupId> <artifactId>SpringData-GemFire-REST-SenchaTouch</artifactId> <version>1.0</version> <packaging>war</packaging> <name>Spring Data</name> <dependencies> <!-- Spring Data GemFire Library --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-gemfire</artifactId> <version>1.3.4.RELEASE</version> </dependency> <!-- GemFire Platform --> <dependency> <groupId>com.gemstone.gemfire</groupId> <artifactId>gemfire</artifactId> <version>7.0.1</version> </dependency> <!-- Spring Data REST MVC --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-rest-webmvc</artifactId> <version>2.0.2.RELEASE</version> </dependency> <!-- Google List API --> <dependency> <groupId>com.google.collections</groupId> <artifactId>google-collections</artifactId> <version>1.0</version> </dependency> <!-- Required Libraries --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> <version>1.0.2.RELEASE</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.1.Final</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>http://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>gemstone</id> <url>http://dist.gemstone.com.s3.amazonaws.com/maven/release/</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>http://repo.spring.io/libs-snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
12. Spring Data REST + Sencha Touch Demo
The demonstration being seen here, shows you the exporting of gemfire repository by using the Spring REST. The message content has been shown while the href of the message has been linked under Message Link link.
13. Summary
This tutorial I have explained, clarify you how to access the Spring Data REST services and GemFire in-memory repository through the Sencha Touch components. If you have any questions, please write it in the comments section.