MVC on the Server and on the Client: How to Integrate Spring MVC and Backbone.js: Sebastiano...

Preview:

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.

Citation preview

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?