Introduction to Reasonable Server Faces - PowerPoint PPT Presentation

1 / 35
About This Presentation
Title:

Introduction to Reasonable Server Faces

Description:

Preview behaviour as well as appearance from the file system ... Internationalization (I18n) Well supported with UIMessage concrete class. Also MessageLocator ... – PowerPoint PPT presentation

Number of Views:87
Avg rating:3.0/5.0
Slides: 36
Provided by: az76
Category:

less

Transcript and Presenter's Notes

Title: Introduction to Reasonable Server Faces


1
Introduction to Reasonable Server Faces
  • Aaron Zeckoski
  • and
  • Antranig Basman

2
Why use RSF?
  • Core RSF Values
  • Completely pure HTML templating
  • Roundtrip with designers without loss
  • Preview behaviour as well as appearance from the
    file system
  • Templates can be reloaded on a live server just
    by dropping in files
  • IoC is built-in
  • No need to "integrate with" Spring, RSF is built
    from Spring
  • IoC in the request scope "refreshes the parts
    other IoC cannot reach" (universal portability
    without code changes)

3
Why use RSF? (contd.)
  • Core RSF Values
  • Stateless design
  • Lightweight EL system allows talk of data "in the
    future" as well as via web services/AJAX
  • Request scope is completely flushed at the end of
    the request
  • Sakai sessions can be gt 50Mb per user. RSF
    encourages designs where session sizes are
    minimized
  • Uses a more PHP-like "running off the DB" model

4
A Sample RSF template
lt?xml version"1.0" encoding"UTF-8"
?gt lthtmlgtltheadgtlttitlegtRSF Itemslt/titlegtlt/headgtltbod
ygt Hello, ltspan rsfid"current-user-name"
gtCurrent Userlt/spangt ltform rsfid"listItemsForm"
method"post"gt lttable class"listHier"gt
lttr rsfid"item-row" gt lttd
class"firstColumn"gt ltspan
rsfid"item-title" gtNon updateable itemlt/spangt
lta rsfid"item-update"
href"AddItem.html?id1"gtNew item titlelt/agt
lt/tdgt lttd rsfid"item-dateCreated"
class"secondColumn"gt Oct 29, 2007 1026 AM
lt/tdgt lt/trgt lt/tablegt lt/formgt lt/bodygt
lt/htmlgt
5
How to use this template?
  • In RSF, there is a complete separation between
    markup and render logic
  • Markup held in an XHTML template decorated with
    rsfid markers
  • Logic held in a Spring-managed (Java) bean known
    as a Producer
  • The job of a Producer is to produce a tree of
    elementary ("primitive") UI components
  • To see how this all fits together, let's look at
    the overall RSF app structure

6
RSF structure and code
7
RSF structure
  • The template (always html) defines the interface
  • The producer (java or xml) defines the view,
    populates the template, and handles navigation
  • ViewParams define the values passed between views
    (get)
  • The requestContext defines producer and backing
    beans
  • The applicationContext defines app scope beans
    and handles rsf app config (via spring)
  • Backing beans handle action processing
  • Logic layer beans can be injected as defined in
    the context xml files
  • Model is basic data POJO

Template (html)
ViewParams (java)
Producer (java)
requestContext (xml)
Backing Bean (java)
applicationContext (xml)
Logic Layer (rest of app)
model (java)
8
RSF templates
Template (html)
  • XHTML files
  • Must be valid XML or runtime error will occur
  • No custom tags used or needed
  • Truly is a pure XHTML template
  • Only uses one custom attribute
  • rsfid - identifies this component for the
    producer

9
Sample template
lt?xml version"1.0" encoding"UTF-8"
?gt lthtmlgtltheadgtlttitlegtRSF Itemslt/titlegtlt/headgtltbod
ygt Hello, ltspan rsfid"current-user-name"
gtCurrent Userlt/spangt ltform rsfid"listItemsForm"
method"post"gt lttable class"listHier"gt
lttr rsfid"item-row" gt lttd
class"firstColumn"gt ltspan
rsfid"item-title" gtNon updateable itemlt/spangt
lta rsfid"item-update"
href"AddItem.html?id1"gtNew item titlelt/agt
lt/tdgt lttd rsfid"item-dateCreated"
class"secondColumn"gt Oct 29, 2007
1026 AM lt/tdgt lt/trgt
lt/tablegt lt/formgt lt/bodygtlt/htmlgt
10
RSF producer
Producer (java)
  • Controls displays logic and populates the
    template with dynamic information
  • Defines a view uniquely
  • By setting a ViewID
  • Recommend you create a public static VIEW_ID
  • Implements ViewComponentProducer
  • Define start page by implementing DefaultView
  • Implement NavigationCaseReporter to control
    submit navigation
  • Implement ViewParamsReporter to receive query
    parameters from http request

11
Sample producer
public class ItemsProducer implements
ViewComponentProducer, DefaultView public
static final String VIEW_ID "Items" public
String getViewID() return VIEW_ID
private CrudPlusLogic logic public void
setLogic(CrudPlusLogic logic) this.logic
logic public void fillComponents(UICont
ainer tofill, ViewParameters viewparams,
ComponentChecker checker)
UIOutput.make(tofill, "current-user-name",
logic.getCurrentUserDisplayName()) UIForm
listform UIForm.make(tofill, "listItemsForm")
ListltCrudPlusItemgt l logic.getAllVisibleIte
ms() for (CrudPlusItem item l)
UIBranchContainer itemrow UIBranchContainer.make
(listform, "item-row") if
(logic.canWriteItem(item))
UIInternalLink.make(itemrow, "item-update",
item.getTitle(), new
AddItemViewParameters(AddItemProducer.VIEW_ID,
item.getId()) ) else
UIOutput.make(itemrow, "item-title",
item.getTitle() )
UIOutput.make(itemrow, "item-dateCreated",
item.getDateCreated() )
12
RSF ViewParams
ViewParams (java)
  • Controls the passing of data between page views
  • Represents query parameters (GET) and URL trunk
    in the abstract
  • extends SimpleViewParameters
  • Should be used when data needs to be sent from
    one view to another
  • Uses URLs in the RESTful way they were designed
  • However, is abstract and typesafe
  • Can be reused on multiple pages

13
Sample ViewParams
  • Is a "Pea" (uses fields rather than
    getters/setters)
  • getParseSpec method is unnecessary unless you
    want fine control over URL structure

14
RSF requestContext
requestContext (xml)
  • Request Scope Context
  • Often called RSAC
  • All RSAC beans are lazy by default
  • Standard Spring bean definition file
  • Uses the Spring file parser code
  • Only includes a subset of the standard
    functionality to increase speed
  • Location of this file is set in the web.xml

15
Sample requestContext
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http//www.springframework.org/dtd/spring-beans
.dtd"gt ltbeansgt lt!-- list the backing beans
here --gt ltbean id"itemsBean"
class"org.sakaiproject.crudplus.tool.ItemsBean"
init-method"init"gt ltproperty
name"logic" ref"org.sakaiproject.cru
dplus.logic.CrudPlusLogic" /gt lt/beangt
lt!-- list the producer beans here --gt ltbean
class"org.sakaiproject.crudplus.tool.producers.It
emsProducer"gt ltproperty name"logic"
ref"org.sakaiproject.crudplus.logic.CrudPl
usLogic" /gt lt/beangt ltbean
class"org.sakaiproject.crudplus.tool.producers.Ad
dItemProducer"gt ltproperty name"logic"
ref"org.sakaiproject.crudplus.logic.Crud
PlusLogic" /gt lt/beangt lt/beansgt
16
RSF applicationContext
applicationContext (xml)
  • A standard Spring bean definition file
  • Puts the beans in the application context
  • Mostly used for configuring RSF
  • Define child of requestAddressibleParent to
    specify beans which can be the target of EL
  • Define child of beanScopeParent to create a new
    session scope for session beans
  • Define a child of CRITemplateResolverStrategy to
    control the location of templates
  • Location of this file set in web.xml

17
Sample applicationContext
lt?xml version"1.0" encoding"UTF-8"?gt lt!DOCTYPE
beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http//www.springframework.org/dtd/spring-beans
.dtd"gt ltbeansgt lt!-- For security purposes, only
beans listed in the comma separated value
list may be the target of EL operations coming
in over the request --gt ltbean parent"requestAddr
essibleParent"gt ltproperty name"value"
value"itemsBean, infoMessages"/gt lt/beangt lt!--
Put this backing bean in session scope --gt ltbean
id"messageBeanScope" parent"beanScopeParent"gt
ltproperty name"copyPreservingBeans"
value"infoMessages" /gt ltproperty
name"exclusive" value"true" /gt lt/beangt
lt/beansgt
18
RSF Backing Bean
Backing Bean (java)
  • Typical bean with methods to handle actions and
    public properties
  • No RSF dependencies
  • Store data needed for processing the user actions
    using public properties
  • Control data model objects with public properties
    (using EL from producer)
  • Process actions using methods
  • Can interact with logic layer
  • But so can the producers
  • Created and destroyed in the request cycle by
    default (recommended practice)
  • Can override this behavior

19
Sample backing bean
public class ItemsBean public CrudPlusItem
newItem new CrudPlusItem() public Map
selectedIds new HashMap() ... private
CrudPlusLogic logic public void
setLogic(CrudPlusLogic logic)
this.logic logic ... public String
processActionAdd() if
(newItem.getHidden() null) //
null here means that the box was not checked
newItem.setHidden( DEFAULT_HIDDEN )
logic.saveItem(newItem)
return "added"
20
Web app basics
  • 4 key things you need to do in a webapp
  • Output dynamic text
  • Render data to the screen
  • Loop structures
  • Output collection or render tables
  • Optional rendering of components
  • Render some components based on state
  • Trigger Actions
  • User actions or data transmission
  • In RSF, these all are done using one part in the
    template and another in the producer (and maybe
    the backing bean for an action method)

21
Output dynamic text
1
Hello, ltspan rsfid"current-user-name"gtCurrent
Userlt/spangt
UIOutput.make(tofill, "current-user-name",
logic.getCurrentUserDisplayName())
  • Uses an rsfid on an HTML entity to show where to
    place the dynamic text
  • Does not have to be a span or div only!
  • UIOutput will send the escaped string to the ID
    location in the component tree
  • Non-escaped output using UIVerbatim
  • Avoid this unless truly necessary

22
Loop structure
2
Use UIBranchContainer and colon tags for looping
structures
ListltItemgt l logic.getAllVisibleItems() for
(Item item l) UIBranchContainer itemrow
UIBranchContainer.make(listform,
"item-row") if (logic.canWriteItem(item))
UIInternalLink.make(itemrow, "item-update",
item.getTitle(), new AddItemViewParameters(
AddItemProducer.VIEW_ID, item.getId()) )
else UIOutput.make(itemrow, "item-title",
item.getTitle() ) UIOutput.make(itemrow,
"item-dateCreated", item.getDateCreated() )
lttable class"listHier"gt lttr
rsfid"item-row"gt lttd
class"firstColumn"gt ltspan
rsfid"item-title"gtNon updateable itemlt/spangt
lta rsfid"item-update"
href"AddItem.html?id1"gtNew item titlelt/agt
lt/tdgt lttd rsfid"item-dateCreated"gtOc
t 29, 2007 1026 AMlt/tdgt lt/trgt lt/tablegt
23
Optional rendering
3
if (item.getHidden().booleanValue())
UIOutput.make(itemrow, "item-title",
item.getTitle() )
ltspan rsfid"item-title"gtHidden item titlelt/spangt
  • HTML entities are rendered if the component is
    tied via the rsfid
  • If there is no UI component matching the id then
    the renderer skips over it
  • A UIOutput can also peer with a tag in the
    template with further component children, to swap
    in or out a whole block of markup

24
Trigger actions
4
ltinput rsfid"add-update-item" type"submit"
value"Add/Update Item" /gt
UICommand.make(addupdateitem, "add-update-item",
"itemsBean.processActionAdd")
public String processActionAdd()
logic.saveItem(updateItem) return "added"
  • Use a normal submit button with an id
  • Use UICommand to tie to an action method in a
    backing bean using EL
  • NB "action methods" are considered an
    old-fashioned form of programming try to use
    BeanGuards instead (more later)
  • Return string ties to a navigation case in the
    producer

25
RSF in practice
26
RSF experience
  • RSF has a moderate learning curve
  • Mostly unlearning poor practices
  • UI components are comprehensive
  • Cover all HTML entities, fairly flexible
  • AJAX integration easy
  • Designed to work well with AJAX and JS
  • Works like a webapp should
  • Normal REST, back button works
  • Easy for UI designers to work with

27
RSF EL
requestwriteablebean.property1.subproperty2
  • A tiny subset of the functionality of JSF
    Expression Language
  • No logic in the expression
  • Sometimes called Value Language (VL)
  • Works with any bean in the request or application
    context
  • More info on the RSF EL page

URL http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?
pageEL
28
OTP (One True Path)
ltinput rsfid"title-input" size"60"
name"title" type"text"/gt
UIInput.make(form, "title-input",
EntryLocator.1.title")
public class EntryLocator implements BeanLocator

ltbean id"EntryLocator" classuk.ac.cam.blogwow.
tool.otp.EntryLocator /gt
  • Defines a single path (EL) to your data
  • Points to a BeanLocator which allows you to tell
    RSF where to find your data
  • Point it at your logic/dao layer
  • RSF 0.7.2 has an automated "EntityBeanLocator"
    which will map to most DAO APIs

29
Internationalization (I18n)
ltb rsfidremove-item"gtAre you sure you want to
remove item (title)?lt/bgt
UIMessage.make(tofill, remove-item",
"remove.item.text", new Object
item.getTitle() )
remove.item.textAre you sure you want to remove
item (0)?
  • Well supported with UIMessage concrete class
  • Also MessageLocator
  • Simple cases can be handled in the template with
    rsfid"msgkey"
  • Takes advantage of the standard Java language
    properties bundle handling
  • Uses the Spring MessageSource for resource
    (properties file) loading
  • Configurable in applicationContext

URL http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?
pageI18N
30
User feedback
ltdiv rsfid"message-for" class"alertMessage"gt
ltul style"margin0px"gtltligtMessage for user
herelt/ligtlt/ulgt lt/divgt
messages.addMessage( new TargettedMessage(user.me
ssage", new Object
item.getTitle() ,
TargettedMessage.SEVERITY_INFO))
user.messageNew item saved (0)
  • Allows for messages generated in a previous
    request to appear in the template
  • No code is required in the receiving template,
    only the element with the rsfid
  • Format of the output messages is configurable

31
Javascript and AJAX
  • RSF does not use AJAX for its own purposes (not
    embedded) so there are no issues with collisions
  • There are some widgets and helpers that are
    included with RSF which use AJAX though
  • RSF includes a Javascript library to make it easy
    to work with the RSF generated element ids
  • Can be tricky to work with because of the way the
    branch nesting works

32
RSF component trees
  • Binds the markup to the model
  • rsfid in the template
  • EL in the producer
  • Tree and components created and destroyed during
    the request cycle
  • Short lived, frees up resources
  • Rooted in a view and only kept around long enough
    to render the view

URL http//www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?
pageComponent
33
RSF structure revisit
  • The template is pure XHTML
  • Easy for UI designers
  • The producer is simple and cleanly defines a view
  • ViewParams abstract out the passing of values
  • The requestContext and applicationContext are
    pure spring config
  • Can be mixed up sometimes
  • Backing beans are really just simple beans

Template (html)
ViewParams (java)
Producer (java)
requestContext (xml)
Backing Bean (java)
applicationContext (xml)
Logic Layer (rest of app)
model (java)
34
RSF resources
  • RSF Wiki (online documentation)
  • http//www2.caret.cam.ac.uk/rsfwiki/
  • RSF forums
  • http//ponder.org.uk/rsf/
  • RSF APIs
  • http//saffron.caret.cam.ac.uk/projects/RSFUtil/ap
    idocs/
  • RSF SVN
  • https//saffron.caret.cam.ac.uk/svn/

35
Questions?
  • RSF
  • http//www2.caret.cam.ac.uk/rsfwiki/
Write a Comment
User Comments (0)
About PowerShow.com