webwork 2 l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
WEBWORK 2 PowerPoint Presentation
Download Presentation
WEBWORK 2

Loading in 2 Seconds...

play fullscreen
1 / 52

WEBWORK 2 - PowerPoint PPT Presentation


  • 202 Views
  • Uploaded on

WEBWORK 2. “Strutting the OpenSymphony way”. Prepared by Mike Cannon-Brookes - June, 2003 mike@atlassian.com - http://www.atlassian.com. Agenda. WebWork 2 & XWork overview Actions Views Interceptors Validation Inversion of Control (IoC) Struts Comparison. WebWork 2 Overview.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'WEBWORK 2' - moeshe


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
webwork 2

WEBWORK 2

“Strutting the OpenSymphony way”

Prepared by Mike Cannon-Brookes - June, 2003

mike@atlassian.com - http://www.atlassian.com

agenda
Agenda
  • WebWork 2 & XWork overview
  • Actions
  • Views
  • Interceptors
  • Validation
  • Inversion of Control (IoC)
  • Struts Comparison
webwork 2 overview
WebWork 2 Overview
  • ‘Pull-based’ MVC framework
  • Focus on componentization & code reuse
  • Implementation of the command pattern
  • Second generation of WebWork
  • Not tied to the web!
  • Currently in beta - but being well used
xwork
XWork
  • Generic command pattern framework
  • Commands represent a unit-of-work
  • Split off from Webwork 1
  • Why command pattern?

WebWork 2

Web

WebWork 1

XWork 1

Non-web

xwork provides
XWork provides…
  • Core command pattern framework for request / response environment
  • Interceptor framework
  • Action chaining
  • IoC componentization framework
  • Runtime attribute validation framework
  • Built-in type conversion using OGNL
  • Doesn’t provide: anything to do with the web!
webwork 2 provides
WebWork 2 provides..
  • Tied to HTTP request / response
  • Integration with session / application scopes
  • Servlet-based dispatcher to turn incoming requests into action/s.
  • Automatically set properties of action based on request parameters
  • View integration (JSP, Velocity etc)
  • User interface / form components
actions
Actions
  • An Action is a command.
  • Each action should be a ‘unit of work’
  • Actions should be simple!
  • Action interface has only one method:

interface Action {

String execute() throws Exception;

}

  • Let’s look at small example…
basic example add pet
Basic Example: Add Pet

Use case - we want to add a Pet to our system:

basic example add pet9
Basic Example: Add Pet
  • A basic example of an action, view and configuration.
    • Model: Pet.java (simple bean)
    • Controller: AddPet.java (WW action)
    • View: addpet.jsp
    • Config: xwork.xml
basic example pet model
Basic Example: Pet Model

. . .

public class Pet {

private long id;

private String name;

public long getId() …

public void setId(long id) …

public String getName() …

public void setName(String name) …

}

basic example addpet action
Basic Example: AddPet action

public class AddPet implements Action {

protected Pet pet = new Pet();

public String execute() throws Exception {

if (pet.getName() == null )

return ERROR;

Registry.getPetStore().savePet(pet);

return SUCCESS;

}

public Pet getPet() {

return pet;

}

}

basic example addpet jsp
Basic Example: addpet.jsp

<%@ taglib uri= "webwork" prefix= "webwork" %>

<html>

<head><title>Add A Pet</title></head>

<body>

<form action= "AddPet.action">

<webwork:textfield label="Name" name="pet.name" />

<input type= "submit" value= "Add">

</form>

</body>

</html>

basic example xwork xml
Basic Example: xwork.xml

<xwork>

<package name="default">

. . .

<action name="AddPet” class="org.petsoar...AddPet">

<interceptor-ref name="defaultStack" />

<result name="error">addpet.jsp</result>

<result name="success">success.jsp</result>

</action>

. . .

</package>

</xwork>

actionsupport
ActionSupport
  • Useful base class, providing:
    • error message support
      • action and field specific errors
      • field errors are automatically supported by views
    • internationalisation support
      • 1 resource bundle per action
      • pervasive UI support for retrieving messages
model driven vs field driven
Model-Driven vs Field-Driven
  • 2 types of Actions possible:
    • Model-driven
      • Action has methods returning your model classes (myAction.getPet())
      • Fields in the view are fields of your model
      • Views refer directly to your model (property=‘pet.name’)
      • Excellent because it allows model reuse
    • Field-driven
      • Action has fields of its own, which are fields in the view
      • execute() collates fields and interacts with the model
      • Views refer to action fields (property=‘name’)
      • Useful where form is not parallel to model
action composition
Action Composition
  • Problem: traditional MVC actions contain duplication or deep class hierarchies
  • Solution: A single WW action can be composed of multiple smaller reusable beans.
  • Before:

public class Signup implements Action {

public String getName(); [+ setter]

public String getHomeInternationalCode(); [+ setter]

public String getHomeAreaCode(); [+ setter]

public String getHomeNumber(); [+ setter]

public String getWorkInternationalCode(); [+ setter]

public String getWorkAreaCode(); [+ setter]

public String getWorkNumber(); [+ setter]

...

}

action composition17
Action Composition
  • After:

public class Signup implements Action {

public String getName(); [+ setter]

public PhoneNumber getHome();

public PhoneNumber getWork();

...

}

public class PhoneNumber {

public String getInternationalCode(); [+setter]

public String getAreaCode(); [+setter]

public String getNumber(); [+setter]

}

  • We can also reduce duplication in our views in the same way - using UI components.
action dispatching
Action Dispatching
  • A Dispatcher configures and executes an action.
  • WebWork has ServletDispatcher and a FilterDispatcher for the servlet environment
  • XWork separates the implementation and invocation of an action
  • ClientDispatcher allows actions created by a client to be executed on server
    • execute an action over RMI (ie in an applet)
    • execute an action via SOAP
webwork views
WebWork Views
  • Multiple supported view technologies:
    • JSP
    • Velocity
    • XML
    • JasperReports
    • … add your own
  • Not being tied to the web allows multiple pluggable ‘result types’
    • - ie action chains, pooling, HTTP redirects etc
view expression language
View Expression Language
  • For expressions WW uses OGNL (Object Graph Navigation Language)
    • Incrementally compiled expressions - fast!
    • Easy to learn, powerful expression language
    • Componentised (so you can embed anywhere)
    • Embedded everywhere - views and *.xml
    • Independently run Open Source project - http://www.ognl.org
ui components
UI Components
  • Powerful for componentization of views
  • Standard form components are built in
    • text field, radio boxes, submit button etc.
  • Skinnable using ‘themes’
    • multiple sets of templates to render same components
  • Usable from any view
    • JSP or Velocity at the moment
ui component usage
JSP:

<ui:textfield label="Username" name="username" />

<ui:password label="Password" name="password" />

<ui:component template="/mytemplate.vm">

<ui:param name="param1" value="value1" />

</ui>

<ui:submit value="'login'" align="right" />

Velocity:

#tag (TextField "label=Username" "name=username")

#tag (Password "label=Password" "name=password")

#bodytag (Component "template=/mytemplate.vm")

#param ("name=param1" "value=value1")

#end

#tag (Submit "value='login'" "align=right")

UI Component Usage
component rendering
Component Rendering
  • <webwork:textfield label="Name" name="project.name" />

looks as follow (with added header) :

  • UI components automatically present field error messages, added by validation framework or action itself:
component rendering25
Component Rendering
  • Uses Velocity to actually render HTML fragments, eg in your JSP view:

<webwork:textfield label="Name" name="project.name" />

renders via textfield.vm:

#parse( "/decorators/xhtml/controlheader.vm" )

<input type="text" name="${tag.Name}"

value="$!{tag.ActualValue}"

#if($tag.Size > 0) size="${tag.Size}"#end />

#parse( "/decorators/xhtml/controlfooter.vm" )

custom components
Custom components
  • WW allows you to easily create custom UI components
  • Requires writing a single Velocity template
  • Excellent for componentizing views (with componentized or model-driven actions)
  • Example: a date picker to allow users to enter dates into text fields easily…
custom component example
Custom component example
  • Here’s the form field and popup:
custom component example28
Custom component example
  • View (addpet.jsp):

<webwork:component label="Created After" template="datepicker.vm" name="pet.created">

<webwork:param name="'formname'" value="'editform'" />

</webwork:component>

  • Component template (datepicker.vm)

#parse( "/decorators/xhtml/controlheader.vm" )

<script language="JavaScript" src="/decorators/datepicker.js" />

<input type="text" name="${tag.Name}" value="$!{tag.ActualValue}" />

<a href="javascript:show_calendar('${tag.Params.get("formname")}', '${tag.Name }');"><img src="/images/icons/cal.gif"></a>

#parse( "/decorators/xhtml/controlfooter.vm" )

interceptors
Interceptors
  • “Practical AOP”
    • very simple, no external dependencies
    • allows you to intercept action invocations.
  • Help decouple and componentize your code
  • Interceptors are organized into ‘stacks’
    • lists of interceptors applied in sequence.
    • applied to any action or package of actions
  • WebWork is mostly implemented as a series of XWork interceptors!
timing interceptor
Timing Interceptor
  • A simple invocation interceptor:

public class TimerInterceptor implements Interceptor {

. . .

public String intercept(ActionInvocation dispatcher) ...{

long startTime = System.currentTimeMillis();

String result = dispatcher.invoke();

long exTime = System.currentTimeMillis() - startTime;

log.info(dispatcher.getProxy().getActionName() + " ran in " + exTime + "ms.");

return result;

}

}

logging interceptor
Logging Interceptor
  • A before/after processing interceptor:

public class LoggingInterceptor extends AbstractInterceptor {

. . .

protected void before(ActionInvocation invocation) ... {

log.info("Starting execution stack for action " + invocation.getProxy().getActionName());

}

protected void after(ActionInvocation invocation, String result) ...{

log.info("Finishing execution stack for action " + invocation.getProxy().getActionName());

}

}

complex interceptor
Complex Interceptor
  • Problem: notifying users of events within our application via email
  • Solution: an XWork interceptor + XML config file
  • The interceptor:
    • parses the config file (if not loaded yet)
    • intercepts the action
    • matches action class & result to determine if any email needs to be sent
    • if it does, processes a Velocity template (email body) and sends it
complex interceptor class
Complex Interceptor - class

public class EventNotifierInt extends AbstractInterceptor {

. . .

protected void after(ActionInvocation actionInvocation, String result) . . . {

List listeners = getListenersFor(actionInvocation, result);

for (int i = 0; i < listeners.size(); i++) {

ConfEventListener l = (ConfEventListener)listeners.get(i);

l.onEvent( result, actionInvocation.getAction() );

}

}

private void loadXmlConfiguration() ...

private List getListenersFor(ActionInvocation invocation, String result) . . .

}

validation framework
Validation Framework
  • Validation of action properties
  • Decoupled from actions
    • validations stored in XML files
    • error messages stored in actions, flow through to UI components
  • Pluggable validator classes
  • Validation is implemented as an interceptor
    • You control when validation happens
example validation
Example Validation
  • adduser-validation.xml

<validators>

<field name="username">

<field-validator type="requiredstring">

<message>Please specify a username.</message>

</field-validator>

</field>

<field name="confirm">

<field-validator type="fieldexpression">

<param name="expression">

confirm == null || password.equals(confirm)

</param>

<message key="passwords.dontmatch">no i18n msg!</message>

</field-validator>

</field>

</validators>

validator class
Validator Class
  • checks that a String field is non-null and has a length > 0

public class RequiredStringValidator extends FieldValidatorSupport {

public void validate(Action action) throws ValidationException {

String fieldName = getFieldName();

Object value = this .getFieldValue(fieldName, action);

if (!(value instanceof String) ||

value == null ||

"".equals((String) value))

{

addFieldError(fieldName, action);

}

}

}

what is inversion of control
What is Inversion of Control?
  • IoC removes the onus of managing components from your business logic into a container.
  • Container manages lifecycles and dependencies between components.
  • EJB is IoC, but with a static list of services
    • Security, persistence and transactions
  • The Jakarta Avalon project is all about IoC.
advantages of ioc
Advantages of IoC
  • Promotes simplicity and decoupling
  • Components describe themselves
  • Dependencies are discovered automatically
  • Adheres to Law of Demeter
    • Classes coupled to only what they use
    • Encourages smaller responsibility classes
  • Leads to better interface/impl separation
  • Unit tests become far simpler
    • they become ‘mini-containers’
ioc in xwork
IoC in XWork
  • First off: IoC can be controversial - it is optional! Use it if it suits you :)
  • XWork and WW provide a web-native IoC architecture
  • Components specify only which services they require
    • via interfaces (eg ShoppingCartAware)
  • Configuration file defines component implementations and scopes.
component scopes
Component Scopes
  • WW has 4 component ‘scopes’ (lifetimes):
    • Application
    • HTTP Session
    • HTTP Request
    • XWork Action
  • Let’s look at an example with 2 services…
ioc example service 1
IoC Example Service #1
  • A ShoppingCart service - provides a user’s cart (session scoped)

ShoppingCartAware.java:

public interface ShoppingCartAware {

public void setShoppingCart(ShoppingCart cart);

}

ShoppingCart.java:

public interface ShoppingCart {

public void addPet(Pet pet);

public void removePet(Pet pet);

public boolean isEmpty();

public int size();

public List getPets();

}

ioc example service 2
IoC Example Service #2
  • A PetStore service - provides management of our pet inventory (application scoped)

PetStoreAware.java:

public interface PetStoreAware {

public void setPetStore(PetStore store);

}

PetStore.java:

public interface PetStore {

void savePet(Pet pet);

void removePet(Pet pet);

List getPets();

Pet getPet( long id);

}

ioc example being serviced
IoC Example -Being serviced!

public class AddToCart implements Action, PetStoreAware, ShoppingCartAware {

. . .

public void setPetStore(PetStore ps) { this.petStore = ps; }

public void setShoppingCart(ShoppingCart c) { this.cart = c; }

public String execute() throws Exception {

if (cart == null || petId == 0)

return ERROR;

Pet pet = petStore.getPet(petId);

cart.addPet(pet);

return SUCCESS;

}

}

ioc example config
IoC Example - Config
  • These services are configured in components.xml like so:

<components>

<component>

<scope>application</scope>

<class>org.petsoar.pets.DefaultPetStore</class>

<enabler>org.petsoar.pets.PetStoreAware</enabler>

</component>

<component>

<scope>session</scope>

<class>org.petsoar.cart.SimpleShoppingCart</class>

<enabler>org.petsoar.cart.ShoppingCartAware</enabler>

</component>

</components>

action packaging
Action Packaging
  • A package is a JAR containing:
    • Actions, views, interceptors, validators, i18n properties and configuration
  • Packages are:
    • namespace aware
    • hierarchical
      • inherit capabilities from super packages
  • Promotes componentisation
packaging configuration
Packaging Configuration
  • xwork.xml:

<xwork>

<package name="default">

. . .

</package>

<package name="subpackage" extends="default">

. . .

</package>

<include file="myotherpackage.xml" />

</xwork>

struts vs webwork
Struts vs WebWork
  • Jakarta Struts is the 500-lb gorilla of the MVC ‘space’
  • No MVC presentation complete without a Struts comparison
    • I’ll try to be unbiased as possible :)
  • Not an apples-for-apples comparison
    • Think of it as a list of differences
webwork pros
WebWork Pros
  • Simpler framework
    • No more writing ‘junk code’ to fulfill Struts’ contracts
  • No more actionbean/formbean classes
    • Use simple model-driven actions and your own model
  • Actions are easy to unit test
    • Instantiate, call setters, run execute()
  • WW ‘plays well with others’
    • Multiple view technologies well supported
webwork pros50
WebWork Pros
  • Simpler views
    • more powerful expression language
    • no more pages with 1000’s of Struts tags
  • No need to make actions thread safe
    • One action instantiated per request
  • Actions not coupled to the web
    • Can be invoked remotely eg ClientDispatcher & RMI
  • Struts has no interceptors, packages, IoC etc
webwork cons
WebWork Cons
  • Not as well supported as Struts
    • No books, tool support etc (changing slowly)
  • Smaller community
  • No action pooling yet
  • Less standards support (eg JSTL & JSF)
    • JSF support might come when spec released
    • JSTL can be done by using tags
  • WebWork not part of Jakarta :)
want more
Want More?
  • http://www.opensymphony.com for website, mailing list, CVS etc
  • http://wiki.opensymphony.com for WW2/XW documentation
  • My blog - http://blogs.atlassian.com/rebelutionary
  • Email me - mike@atlassian.com
  • One chapter of my upcoming book on real world development with Java OSS technologies

</shameless-plug>

Thank you for listening - questions?

Mike Cannon-Brookes

ATLASSIAN - www.atlassian.com

with XDoclet,

JUnit,WebWork

& Hibernate