mvc on the server and on the client: how to integrate spring mvc and backbone.js: sebastiano...
DESCRIPTION
MVC is a well-known pattern used to reduce complexity and to increase reusability of your code, widely adopted in server-side languages. Spring MVC is an example of a really powerful framework that adopts this pattern extensively allowing you to create easily RESTful web services. MVC can also be applied to the client now and this approach really suits AJAX applications and single page applications. Backbone.js is one of the frameworks available to enforce this pattern. In this session we will explore how well you can integrate Spring MVC and Backbone.js in a really performant and neat single page application. Focus will be put on how Backbone.js can consume RESTful web services.TRANSCRIPT
Sebastiano Armeli-Battana@sebarmeli
July 10 , 2012 JAXConf, San Francisco
MVC on the server andon the client
How to integrate Spring MVC andBackbone.js
Architectural Design Pattern
Business logic / presentation layer
Reusability
Components isolation
Model - View - Controller
Model
View Controller
Passive Approach
Active Approach
Passive and Active MVCModelView
Controller
Model
ViewController
Observerpattern
Java and MVC
POJO
JSP
Servlet
Model
View
Controller
Spring MVCFront Controller pattern
Getting started
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
web.xml
Spring MVC 3 configurations
<mvc:annotation-driven />
dispatcher-servlet.xml
<mvc:view-controller path=”/page1” view-name=”view1” />
<mvc:resources mapping=”/resources/**” location=”/resources” />
<context:component-scan base-package=”com.example”
<beanclass="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name=”mediaTypes”> ... </property> <property name=”viewResolvers”> ... </property></bean>
Spring MVC in action
Service Layer (@Service)
@Controllerpublic class ContactsController {
@Autowired private ContactService service;
@RequestMapping(value=”/list”, method = RequestMethod.GET) public @ResponseBody List<Contact> getContacts() {
return service.getContacts(); }}
[{ “id” : 31, “firstname” : “LeBron”, “lastname” : “James”, “telephone” : “111-222-3333”}]
DAO (@Repository)
MODEL
VIEW
CONTROLLER
What about the Model?
@Entity@Table(name=”Contacts”)public class Contact { @Id @Column(name = ”ID”) @GeneratedValue private Integer id;
@Column(name = “FIRSTNAME”) private String firstname;
public String getFirstname(){ return firstname; } public void setFirstname(){ this.firstname = firstname; }
...}
Why MVC in JavaScript ??
AJAX application with lots of JS code
Managing efficiently jQuery selectors and callbacks
Decoupling components
Simplify communication with RESTful WS
JavaScript and MVC
JS object
HTMLTemplate
JS object
Model
View
Controller
JavaScript ‘MVC’ / ‘MV*’ Library
Dependencies: - Underscore.js - json2.js - jQuery / Zepto
Single Page Application (SPA)
Connection to API over RESTful JSON interface
RESTful JSON API
$(function(){
// stuff here Backbone.history.start();});
Model
MyApp.Contact = Backbone.Model.extend({
defaults: { firstname : “”, lastname : “”, telephone : “” },
getFullName: function() { return this.fullname + this.lastname; },
validate: function(){} });
var newContact = new MyApp.Contact();newContact.set({‘firstname’ : ‘Lebron'});
Represents data (JSON)
Key-value attributes
Domain-specific methods
Custom events &Validation
{ “id” : 31, “firstname” : “LeBron”, “lastname” : “James”, “telephone” : “111-222-3333”}
Collection
MyApp.Contacts = Backbone.Collection.extend({
model: MyAppp.Contact,
url: ‘/list’ });
var collection = new MyApp.Contacts(), model1 = new MyApp.Contact();
collection.add(model1);
Set of models
url / url()
create() / add() / remove()/ reset()
get() / getByCid()
Router
MyApp.AppRouter = Backbone.Router.extend({
routes: { “” : “index”, “list-contacts” : “listContacts” },
index : function() { // stuff here }
listContacts : function() { // stuff here }});
var router = new MyApp.AppRouter();
Routing client-side “states”
“routes” map
List of actions
MyApp.ListContactsView = Backbone.View.extend({
className: ‘list’,
initialize: function(){ // stuff here },
events: { “click a”: “goToLink” } goToLink : function() {}
render : function(){this.$el.html(“<p>Something</p>”); }});
var view = new MyApp.ListContactsView();view.render();
Logical view
‘el’ attribute
Event handlers
render()
View
MyApp.ContactsView = Backbone.View.extend({
...
render : function(){ var obj = this.model.toJSON(), template = ich.contactTemplate(obj);
this.$el.html(template); }});
var view = new MyApp.ContactsView();view.render();
Pick one client-side templating engine!(E.g. Handlebars.js, Haml-js, ICanHaz.js)
Isolate HTML into Template
View + HTMLTemplate
<script type=”text/html”id=”contactTemplate”><p>First name : {{firstname}}</p><p>Last name : {{lastname}}</p><p>Telephone : {{telephone}}</p>script>
View
HTML template
ICanHaz.js
Model-View binding
var view = Backbone.View.extend({
initialize: function(){
this.model.bind(“change”, this.render, this);
},
render : function(){}
});
Backbone.js and RESTBackbone.sync(): CRUD => HTTP Methods
(jQuery/Zepto).ajax()
collection.create(model) / model.save()
collection.fetch() / model.fetch()
model.save()
model.destroy()
POST
GET
PUT
DELETE
‘My Contacts’ Application
REST API
URI HTTP Method
/list GET
/list POST
/list/{contactId} PUT
/list/{contactId} DELETE
Questions?