SpringSurf is a web framework built on Spring MVC that provides components, templates, and pages for composing web applications. It originated from Alfresco's Surf framework in 2007. In 2009, Surf was integrated with Spring and contributed as an open source project called SpringSurf. SpringSurf allows defining pages using XML and templates using FreeMarker. Components can be developed using JavaScript and connect to remote APIs. Model objects and artifacts can be stored locally or remotely. SpringSurf provides rapid development of web applications and extensions.
Boost Fertility New Invention Ups Success Rates.pdf
Spring Surf 101
1. SpringSurf 101 2 Kevin Roast UI Team Leader, Alfresco twitter: @kevinroast
2. SpringSurf 101 3 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?
3. SpringSurf 101 4 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...
4. SpringSurf 101 5 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...
5. SpringSurf 101 6 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?
6. SpringSurf 101 7 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?
7. SpringSurf 101 8 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
8. SpringSurf Model 9 Pages Home Profile Products Regions Component varconn = remote.connect("alfresco"); varjson = conn.get("/api/products/" + args.filter); if (json.status == 200) { // Create JavaScript objects from the response varobj = eval('(' + json + ')'); if (obj) { ... Perform processing on the js objects // set results into the model for the template model.results = somearray; } } Template Instance
9. SpringSurf 101 10 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
10. SpringSurf Model 11 Page Instance SiteConfig Template Instance Template Theme Template type Regions Chrome Component Binding Component Component type
14. SpringSurf 101 15 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
15. SpringSurf 101 16 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
16. SpringSurf 101 17 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: UriTemplateconfig URL Mapping
18. SpringSurf 101 19 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} argsmap formdataform fields (including files) page, page.url, config, user, htmlidobjects Request Context - context Request parameters, attributes, headers WebScript Component APIs
19. SpringSurf 101 20 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
20. Remote API – component controller 21 products.get.js varconn = remote.connect("alfresco"); varjson = conn.get("/api/products/" + args.filter); if (json.status == 200) { // Create JavaScript objects from the response varobj = eval('(' + json + ')'); if (obj) { ... Perform processing on the js objects // set results into the model for the template model.results = somearray; } }
21. Remote API – component template 22 products.get.html.ftl <div class="products" id="${htmlid}-products"> <#list results as r> <div class="product">Name: ${r.name?html}</div> </#list> </div>
23. SpringSurf 101 24 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
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 26 Rapid Development Lifecycle
27. SpringSurf 101 28 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?
28. SpringSurf 101 29 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?
29. SpringSurf 101 30 Continue use by Alfresco projects, customers, partners... DOCUMENTATION!!! (sorry) Where is it going and what is missing?
30. Learn More 31 Blog 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.org http://forum.springsource.org/forumdisplay.php?f=72
Editor's Notes
Quick bio:Kevin Roast - UI Team Leader, one of the founding Alfresco developers, worked on the Explorer JSF based client, the JavaScript and FreeMarker services and repository APIs, impl some of the features in Alfresco WebScripts, came up with the PageRenderer WebScript runtime which is the “core” of the SpringSurf rendering tech used in Alfresco Share – i.e. “WebScripts as UI components” – more on to that later…Introduction to SpringSurf – not a deep dive - we will examine the basics of the SpringSurf view composition framework for Spring MVC applications. Hope to show how to easy to construct pages, templates and components that can be used to quickly build web applications fromsimple scripts and templates.
WebScripts been around for more than 3 years in some form or anotherSurf has been around for over 2 yearsElaborate on important points in the history
M3 -> RC1 we’ve come a long way...RC1 is a revelation compared to stability, performance and test coverage since M3... Features a large suite of tests for functional area coverage.
What can you do with it? – Simple REST APIs to complete Rich web applications!WebScript pure REST API tier i.e. separate application – Activiti project; has a pure WebScript based REST API tier exposing new BPM engine (server), plus a SpringSurf based web-application consuming the REST APIs (UI). A mix of Java and JavaScript backed webscripts and FTL based pages <- mention Erik’s blog posts, download Activiti etc.WebQS, Mobile.
Why should you use it?Familiar with SpringMVC? Then this will make building views quicker, less (a lot less!) Java code (annotations yuk) and can use lovely WebScripts.Fast, powerful APIs, rapidRAPID dev cycle. Extend Share – jar packaging.Share uses it, WebQS, OpenCMIS and Activiti use itDeveloper tools coming!
Views (pages), templates, components – WebScripts, FreeMarker, JS, head templates, JSP, chrome.Page, can specify template instance to use (another xml descriptor) – otherwise Surf will “use template with the same name” but can reuse templates i.e. a product template can be used by multiple pages. Reused of pages, templates.Components can be global, template or page scoped – also uri or theme scope – unique to the URL (mostly same as page, but not if you use URL templates) and theme specific
Helps to identify the link between pages, template instances, templates and components
Surf model objects can be created, modified and persisted – they all respond to APIs – think dynamic dashboards in Share – could have real-time drag and drop if you felt that would provide the best UI experience...
Helps to identify the link between pages, template instances, templates and components
If you have no template scoped components, or template specific properties - then you don’t need this! Surf will automatically attempt to find “products.ftl” and internally generate an intermediary object to represent the template instanceNote the embedded template scoped component defs
Note the ${head} freemarker model value – combined result of all components .head.ftl templates – well formed HTMLRegion tags themselves can be dynamic!i.e.<#list comps as c><@region id=“${c}" scope=“${something}" /></#list>Surf will work out what components are present on the page before pre-generating the ${head} contents.Simple DIV structure, use CSS for layout magic (also YUI in Share – entirely up to you what libs you use! JQuery etc.)Example template with region component bindings, examples of global, template and page scoped (next slide for detail)
<scope>page</scope> <region-id>title</region-id> <source-id>console</source-id>For uri/theme scopeWith nested components defs, only global scoped components tend to be defined in individual XML files – lot, lot less XML files than in 3.2 – see Share 3.4 for comparison!
Allows simple urls and multiple URLs (i.e. Spring Views) to Share the same SpringSurf Page instance
UI component WebScript component “contract”:Don’t output full page HTML i.e. Just an HTML fragmentOutput clean HTML consistent with parent page i.e. XHTML, HTML5Use .head.ftl template for dependant client-side files i.e. CSS, JSCan assume running in page context i.e. use of “page.url.args” is ok – but better to “bind” args into component URLEncode HTML with ?html and encode JS with ?js_string <- XSS!
If GET, can simplify to – remote.call(“/...”);Use eval() for JSON response – or use E4X to process XML responsePlace any processed JS objects into the “model” – generally an array of objects or just an object – will automatically be marshelled into FreeMarker object equivalents i.e Array to List, Object to MapCan just put the eval-ed resulting object directly into the model without further processing if required, but most scripts do some processing of the data in JS – remember if “production” mode the JS is compiled so quick (but not as quick as Java or modern JS engine like V8...)Get/post/put/delete on the connector objectImagine processing formdata form client, placing into a json structure and POSTing to an API – very quick and easy to do.
Walk arrays as lists or access object properties from the model – easy and fast
Full component model not available (special template – not running as a true WebScript presentation template) – but access to “page” etc. as you would expect i.e. args available
Adding a persister via SpringSurfModel objects will now be retrieved from remote Alfresco store by default (cached of course)Model objects can be save()ed to the remote store
Runtime: selects the “persister” group – WEB-INF (webapp), classpath locations (surf/), local is a folder on disk, alfresco is alfresco specific classpaths (alfresco/) i.e. Old Surf apps and Alfresco ShareDevelopment mode: selects the caching settings for the model objects loaded by the persitsers – runtime uses aggressive caching – will *need* to Refresh via console if adding files at runtime. The “development” mode disables caches. Note that WebScript components will still need Refresh-ing as the WebScript registry is populated once during server startup.
Mention blog post on JAR packaging for ShareSince 3.4.b it is possible to override Share web-assets also (fixed to use the /res resource controller for all assets – so can override on classpath or JARs)