Uploaded on

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.

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.

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
3,376
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
87
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • 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
  • Example page def – note embedded page scoped component defs (since 3.3)Custom properties
  • 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)

Transcript

  • 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
  • 11. products.xml (page)
    12
    <?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>
  • 12. products-template.xml (template instance)
    13
    <?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>
  • 13. products.ftl
    14
    <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>
  • 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
  • 17. UriTemplate configuration
    18
    <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>
  • 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>
  • 22. Component .head.ftl template
    23
    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>
  • 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
  • 24. Remote Persister Spring Config
    25
    <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>
  • 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
  • 26. Development Configuration (surf.xml)
    27
    <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>
  • 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