Spring Surf 101

30
SpringSurf 101 1 Kevin Roast UI Team Leader, Alfresco twitter: @kevinroast

description

In this session, we will examine the basics of the SpringSurf view composition framework for Spring MVC applications. It will show how to easily construct pages, templates and components.

Transcript of Spring Surf 101

Page 1: Spring Surf 101

1

SpringSurf 101

Kevin RoastUI Team Leader, Alfresco

twitter: @kevinroast

Page 2: Spring Surf 101

2

SpringSurf 101

• Introduction• Who am I?• What is this all about?

• Just a quick history lesson...• What can you do with it?• Why should you use it?• Views, templates, components.• URL mapping• Remote API• How do I use it?• Where is it going and what is missing?

Page 3: Spring Surf 101

3

SpringSurf 101

• 2007• Alfresco 2.0 introduces first REST API (early WebScripts concepts)• Alfresco 2.1 introduces WebScripts

• REST framework, JSR-311 (Jax-RS) URI Index• Scriptable controllers (or backed by Spring Java Beans)• FreeMarker template output (or Java output stream)

• 2008• Alfresco Web Framework demo-ware (model objects, JSP, FTL)• Alfresco Page Render (WebScripts as components on a page)• Combined, productised and renamed to Surf• Alfresco Share 3.0, 3.1 – Alfresco collaboration and DM – modern

XHTML and Ajax based interface

Just a quick history lesson...

Page 4: Spring Surf 101

4

SpringSurf 101

• Early 2009• Alfresco Share 3.2• First contact between Alfresco and SpringSource

• Late 2009• Alfresco Surf and WebScripts integrated with SpringMVC• Alfresco Surf and WebScripts contributed as Spring Extension – SpringWebScripts and SpringSurf

• Alfresco Share 3.3 – refactored onto SpringWebScripts and SpringSurf!

• 2010• 3 Milestones and RC1 release• Alfresco Share 3.4 – using SpringSurf RC1

• 2010-2011?• RC2, 1.0

Just a quick history lesson...

Page 5: Spring Surf 101

5

SpringSurf 101

• Rapid web-tier view composition – SpringMVC View Resolver

• FreeMarker, JSP, Groovy, PHP pages•WebScript, FTL, JSP, Groovy, PHP components• Simple JavaScript, Groovy controllers• Remote API – REST request/response processing• WebScripts – standalone REST API tier• Portlets (RC1)

What can you do with it?

Page 6: Spring Surf 101

6

SpringSurf 101

• View composition plug-in for Spring Web MVC• Varied choice of scripting/templating technologies• Simple but powerful APIs• URI template mappings – clean URLs, page reuse• Rapid *rapid* development cycle• Output any text format, any HTML format (i.e. XHTML,

HTML5)• Extensions for Alfresco Share – JAR packaging• Alfresco Share, WebQS, OpenCMIS and Apache Activiti• Developer tools in progress• Continuing development via SpringSource

Why should you use it?

Page 7: Spring Surf 101

7

SpringSurf 101

• Views (pages) – simple XML definition• FreeMarker HTML templates, simple DIV based structure,

component bindings, that’s it.• Page->Template->Component• products.xml• products.ftl• Region component bindings

Views, Templates, Components

Page 8: Spring Surf 101

8

SpringSurf Model

Home

Products Profile

var conn = remote.connect("alfresco");var json = conn.get("/api/products/" + args.filter);if (json.status == 200){ // Create JavaScript objects from the response var obj = eval('(' + json + ')'); if (obj) { ... Perform processing on the js objects // set results into the model for the template model.results = somearray; }}

Pages

Regions

Template Instance

Component

Page 9: Spring Surf 101

9

SpringSurf 101

• Everything is an object! Including component bindings.• CRUD operations via web-tier JS API• Easy dynamic get/set of object properties

object.properties["name"] = value;

• new() and save() objects to persist dynamically i.e. Alfresco Share dashboards

Model Objects

Page 10: Spring Surf 101

10

Chrome

SpringSurf Model

PageInstance

Template Instance

Template

ComponentBinding

Component

Template type

Regions

Component type

Theme

SiteConfig

Page 11: Spring Surf 101

11

products.xml (page)

<?xml version='1.0' encoding='UTF-8'?><page> <title>New Products Page</title> <description>Page displaying newest products</description> <template-instance>products-template</template-instance> <authentication>user</authentication> <components> <component> <region-id>productlist</region-id> <url>/components/productlist?filter=new</url> </component> </components> <properties> <maxresults>100</maxresults> </properties></page>

Page 12: Spring Surf 101

12

products-template.xml (template instance)

<?xml version='1.0' encoding='UTF-8'?><template-instance> <title>Product Template</title> <description>Common products template</description> <template-type>products</template-type> <components> <component> <region-id>treeview</region-id> <url>/components/navigation/treeview</url> </component> </components></template-instance>

Page 13: Spring Surf 101

13

products.ftl

<html> <head>${head}</head> <body> <div id="..." class="..."> <@region id="header" scope="global" /> </div> <div> <@region id="treeview" scope="template" /> <@region id="productlist" scope="page" /> </div> <div> <@region id="footer" scope="global" /> </div> </body></html>

Page 14: Spring Surf 101

14

SpringSurf 101

• Components defined in page XML are page scope – “single use” components specific to a particular page e.g. admin console widget

• Components defined in template instance XML are template scoped – e.g. common tree navigation component

• Can define component bindings by declaration – like WebScript artifacts e.g. page.title.console.xml

• Global scoped component – header, footer etc.• Template scoped components• Page scoped components

Component Scopes

Page 15: Spring Surf 101

15

SpringSurf 101

• Chrome• Template fragment executed to wrap “chrome” around

a component – for example default “region” chrome:<div id="${htmlid}"> <@component/></div>

• Themes• Objects that encapsulate the information required to

define a new look and feel for an app• Alfresco Share 3.4 – good example

Chrome and Themes

Page 16: Spring Surf 101

16

SpringSurf 101

• http://yourserver:8080/yourapp/products• /all/products /new/products• /old/products /bestselling/products• Don’t want to define multiple pages that do same thing

(even with reuse of templates)• Either want to reuse the same page instance• And or require some information from the url• Can use: urlrewrite.xml• Can use: UriTemplate config

URL Mapping

Page 17: Spring Surf 101

17

UriTemplate configuration

<config evaluator="string-compare" condition="UriTemplate"> <uri-templates> <uri-template id="products"> /{filter}/products </uri-template> <uri-template id="userprofile"> /user/{userid}/{pageid} </uri-template> </uri-templates></config>

Page 18: Spring Surf 101

18

SpringSurf 101

• UI Components must “behave” and follow loose contract• Usual WebScript artifacts – bound by URL

• I18N messages via localisable properties file• Component configuration (XML) via config.xml file

• GET/POST to page – automatic fall back to GET impl• HEAD template webscriptid.get.head.ftl ${head}• args map• formdata form fields (including files)• page, page.url, config, user, htmlid objects• Request Context - context

• Request parameters, attributes, headers

WebScript Component APIs

Page 19: Spring Surf 101

19

SpringSurf 101

• Connectors• Authenticators• XML configure access to “endpoints” – obtained by id• Access HTTP methods through JS code or Ajax via proxy controller• Endpoints hide the URL stem from scripts – authentication encapsulated

by connectors and authenticators<endpoint><id>alfresco</id><name>Alfresco - user access</name><connector-id>alfresco</connector-id><endpoint-url>http://myserver/alfresco/s</endpoint-url><identity>user</identity>

</endpoint>

• Connect to multiple REST sources; alfresco, wiki, search

Remoting API

Page 20: Spring Surf 101

20

Remote API – component controller

products.get.js

var conn = remote.connect("alfresco");var json = conn.get("/api/products/" + args.filter);if (json.status == 200){ // Create JavaScript objects from the response var obj = eval('(' + json + ')'); if (obj) { ... Perform processing on the js objects // set results into the model for the template model.results = somearray; }}

Page 21: Spring Surf 101

21

Remote API – component template

products.get.html.ftl

<div class="products" id="${htmlid}-products"> <#list results as r> <div class="product">Name: ${r.name?html}</div> </#list></div>

Page 22: Spring Surf 101

22

Component .head.ftl template

products.get.head.ftl

<link rel="stylesheet" type="text/css" href="${page.url.context}/products/products.css" />

<script src="${page.url.context}/products/products.js"></script>

Page 23: Spring Surf 101

23

SpringSurf 101

• Persisters – read model object definitions from classpath, WEB-INF, JARs

• Alfresco legacy locations and Spring “friendly” locations• Migration of Alfresco Surf 3.2 apps• New locations require less files, folders

• Read and write to remote location and local file system• Example - Alfresco Share stores pages and components

for dynamic dashboards in the repository

Model Object Stores

Page 24: Spring Surf 101

24

Remote Persister Spring Config<bean id="webframework.slingshot.persister.remote" class="org.springframework.extensions.surf.persister.PathStoreObjectPersister” parent="webframework.sitedata.persister.abstract"> <property name="store" ref="webframework.webapp.store.remote" /> <property name="pathPrefix"> <value>alfresco/site-data/${objectTypeIds}</value> </property></bean>

<bean id="webframework.objects.persister" class="org.springframework.extensions.surf.persister.MultiObjectPersister"> <property name="serviceRegistry" ref="webframework.service.registry" /> <property name="persisters"> <list> <!-- Slingshot remote store persisters --> <ref bean="webframework.slingshot.persister.remote" /> ... </list> </property> <property name="defaultPersister"> <ref bean="webframework.slingshot.persister.remote" /> </property></bean>

Page 25: Spring Surf 101

25

• Page, templates, components, webscripts – ALL dynamically refresh via WebScripts and Surf console pages

• /service/index• /service/console• Console Information View• Refresh WebScripts, Refresh Object Registry• Use exploded WAR folders/files during development – copy

over and Refresh

SpringSurf 101

Rapid Development Lifecycle

Page 26: Spring Surf 101

26

Development Configuration (surf.xml)

<alfresco-config><config evaluator="string-compare" condition="WebFramework">

<web-framework><!-- Autowire Runtime Settings --><autowire> <!-- Runtime: classpath, webapp, local, alfresco -->

<!-- <runtime>classpath</runtime> --> <runtime>webapp</runtime> <!-- <runtime>local</runtime> --> <!-- <runtime>alfresco</runtime> --> <!-- Pick the mode: development, production --> <mode>development</mode> <!-- <mode>production</mode> --></autowire>

</web-framework></config>

</alfresco-config>

Page 27: Spring Surf 101

27

SpringSurf 101

• SVN checkout, maven build – www.springsurf.org• https://src.springframework.org/svn/se-surf/trunk• https://src.springframework.org/svn/se-surf/tags/release-1.0

.0-RC1• Maven project• Example application WAR files (initial config etc.)

• Quick Start, Spring Pet Clinic, Spring Travel• Look at Share, WebQS, Mobile, Activiti...

• Dev tools!

How do I use it?

Page 28: Spring Surf 101

28

SpringSurf 101

• Alfresco Share JAR file extensions• Add or extend Alfresco features via simple JAR file

packaging• Drop in JAR to Share, restart app-server – done.• See Alfresco blogs:

• alfresco-share-33-extensions-and-springsurf

How do I use it?

Page 29: Spring Surf 101

29

SpringSurf 101

• Continue use by Alfresco projects, customers, partners...• DOCUMENTATION!!! (sorry)

Where is it going and what is missing?

Page 30: Spring Surf 101

30

Learn MoreBlog posts:http://blogs.alfresco.com/wp/ewinlof/http://blogs.alfresco.com/wp/kevinr/http://mindthegab.com/http://drquyong.com/myblog/

SpringSurf site and forums:http://www.springsurf.orghttp://forum.springsource.org/forumdisplay.php?f=72