Migrating from Struts to JavaServer Faces - · PDF fileWhat is JavaServer Faces? Standard web...

74
Migrating from Struts to JavaServer Faces Tips and techniques for migrating or integrating a Struts application with JavaServer Faces Kito D. Mann [email protected] http://www.manning.com/mann/ http://www.jsfcentral.com Philadelphia Java User's Group July 19th, 2005 Copyright © 2005 Virtua, Inc.

Transcript of Migrating from Struts to JavaServer Faces - · PDF fileWhat is JavaServer Faces? Standard web...

Migrating from Struts to JavaServer Faces

Tips and techniques for migrating or integrating a Struts application with JavaServer Faces

Kito D. [email protected]

http://www.manning.com/mann/http://www.jsfcentral.com

Philadelphia Java User's Group

July 19th, 2005

Copyright © 2005 Virtua, Inc.

Kito D. Mann

● Hands-on enterprise architecture consultant and author

● Author, JavaServer Faces in Action (Manning Publications)

● Founder, JSF Central– http://www.jsfcentral.com– JavaServer Faces Development Community– News, FAQ, links, and so on

● Member of the JSF 1.2, JSP 2.1, and Design-Time API for JavaBeans expert groups

● Experience with Java since its release in 1995● Web development since 1993

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

Many different frameworks

● Two types of frameworks:– Foundation

● Struts, WebWork, Maverick, many others– User interface

● Tapestry, SOFIA, many others● Over 30 different Java web development frameworks

available● Framework paralysis!● JSF is a standard best-of-breed framework● Java needed a competitor to Microsoft's ASP.NET

WebForms

What is JavaServer Faces?

● Standard web user interface framework for Java● Defines UI component and event model, standard UI

components, and application infrastructure● UI components live on the server● Client-generated events are handled on the server● Can automatically synchronize UI components with

application objects● Extensive tool support (Sun, IBM, Oracle, others) ● Enables RAD-style approach to Java web

development● Sets stage for third-party UI component market● Built on top of Servlet API● Works with JSP, but does not require it

JSF and Struts 1.x● JSF is UI

framework● Services overlap

with Struts● Can be used

with Struts

What is JavaServer Faces?JSF Application Architecture

Key JSF concepts

● User interface (UI) components● Renderers● Backing beans● Validators● Converters● Events and listeners● Navigation● Expression language● Messages

User interface components

● Objects that manage interaction with a user● May be responsible for its own display, or may

delegate display to a renderer● Stored in a tree on the server (“view”)● Retain state inbetween client requests● Standard components: text box, panel, label, data

grid, graphic, listbox, radio button, check box, and so on

● Other possibilities: toolbar, menu, RSS viewer, tabbed pane, file upload, and so on

Renderers

● Responsible for encoding and decoding components

● Encoding displays the component● Decoding translates the user's input into component

values or events● Grouped into render kits

– JSF ships with an HTML 4.01 render kit– Render kits can implement a look and feel (“skin”) – Render kits can target a specific device (phone, PC)

or markup language (WML, HTML, SVG)– The render kit can be changed on the fly

Backing beans

● Collect form input from components● Properties can be synchronized with component

values● Can reference and manipulate UI component

instances● Handle UI events● A combination of Struts ActionForms and Struts

Actions● Conceptually similar to code-behind classes in

ASP.NET WebForms ● Usually talk to model objects to execute actual

business logic

Validators

● Validators verify that a component's value is acceptable

● A UI component can be associated with one or more validators

● Validation can also be handled by backing bean methods

● JSF includes standard validators for checking range and length

● Example: <h:inputText id="helloInput" value="#{helloBean.numControls}" required="true"> <f:validateLongRange minimum="1" maximum="500"/> </h:inputText>

Converters● Convert value of the

component to and from a String for display

● Perform formatting or localization

● Standard converters for all basic Java data types

● Example: <h:outputText value="#{user.dateOfBirth}"> <f:convertDateTime type="date" dateStyle="short"/> </h:outputText>

Events and listeners

● Uses JavaBean event model (like Swing)● Objects create events which are consumed by

listeners● Listeners can be implemented as backing bean

methods (unlike Swing) or separate listener classes (like Swing)

● Action methods – special listeners that perform logic and impact navigation

● Standard events– Action events (user clicked on a button or link)– Value-change events (value of control changed)– Data model events (new row in data set selected)– Phase events (used when processing a request)

Navigation

● Full support for declarative navigation

● Outcome of action methods used to select next page

● Eliminates need for Java code or JSPs to know file names

<navigation-rule> <from-view-id>/login.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/mainmenu.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/login.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>mainmenu</from-outcome> <to-view-id>/mainmenu.jsp</to-view-id> </navigation-case> </navigation-rule>

The JSF expression language

● Used to associate UI component properties with backing beans and model objects

● Based on EL included in JSP 2.0● Properties are referenced with value binding

expressions: #{myBean.myProperty}● Methods are referenced with method binidng

expressions: #{myBean.myMethod}● Supports mixed literal values and implicit variables● Can interact with same objects as JSP 2.0 and JSTL

tags (or rest of web application)● Extensible API for creating and evaluating

expressions in Java code

Messages

● Built-in support for application messages● Messages created by validators, converters, or

application code● Can be displayed by UI components

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

What is Struts Shale?● Next-generation web framework

– Proposed by Craig McClanahan in November, 2004– Built on top of JSF– Individual layers (like shale rock)

● Application controller– Pre and post-processing of requests – Uses a servlet filter – Uses chain-of-command pattern (Commons Chain)

● View controller– JSF managed bean with lifecycle events– 1:1 relationship between view logic (Java class) and

view template (JSP, etc.)

What is Struts Shale?● Dialog framework (web flows)● Unit testing framework● “Clay” plugin

– Tapestry-style HTML views– Sub-trees and composition

● Use-case application● Other features

– Client-side validation (Commons Validator)– Spring integration– Remoting (Ajax support)

● Most of core framework completed

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

When to use JSF with other frameworks

● JSF's primary purpose is to provide a standard UI framework and basic application infrastructure so that choosing another framework isn't a requirement

● It's young, so may not have all features of other frameworks

When to use JSF with other frameworks

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and

responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

The many faces of requests and responses

● In JSF terminology, there are two types of requests, and two types of responses:– A Faces Request is any client request that’s processed

by the normal JSF Request Processing Lifecycle – A Faces Response is any response that is generated by

the JSF Framework● Does not include responses that aren't JSF views

– A Non-Faces Request is any request that was not initiated by a JSF component

– A Non-Faces Response is any response that wasn’t created by the JSF Framework

● Usually, Faces Requests generate Faces Responses

The many faces of requests and responses

● There are four different Faces Request / Response scenarios:

The many faces of requests and responses

● This level of flexibility also allows you to integrate with non-JSF resources (servlets, JSPs, HTML files, and so on) in the same web application

● Struts-Faces integration library uses a mixture of Faces and Non-Faces requests and responses

● The ability to mix and match JSF processing also makes it easy to migrate your applications over time– Your existing application and JSF both use the

Servlet API– They can access the same application logic

Agenda

● JavaServer Faces (JSF) overview● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

Migration and integration strategies

● JSF's extensible architecture allows for a variety of approaches for working with existing applications– Component-only migration/integration

● Most conservative option– Incremental migraiton– Complete migration

Component-only migration● Allows you to take advantage of the growing UI

component marketplace while minimizing the cost of rewriting existing elements of your applications

● Good option when you have a large, complex application and limited amounts of time

● Usually requires an integration library, like Struts-Faces or JSF-Spring– Struts-Faces allows you to build UIs using JSF

components while using your existing Struts actions– Has specialized JSF event listeners that execute the

Struts request processing chain

Component-only migration– Struts actions and forwards work as usual, and are

unaware of JSF– Struts and JSF servlets both execute within the same

web application● They can also share variables and application logic

Component-only migration– The same principal works for integrating with other

frameworks

Incremental migration● Good choice for complete migration to JSF● Allows you to begin taking advantage of JSF's

benefits quickly– Minimal impact on existing infrastructure

● Well suited when:– You must continue to roll out new features while

upgrading to JSF at the same time– You are using agile development approaches

● Each release can include migration of a specific portion of the application

Incremental migration● Also requires integration libraries such as Struts-Faces● Component-only migration can be the first step● Once a view have been migrated, the next step is to

move the associated application logic to JSF backing beans

● If application is layered (business logic is in separate domain-specific objects), moving the application logic is a fairly trivial task – The code in the web layer is relatively trivial

● Executes business logic classes, evaluates the result, and directs the user to the proper response page

● Migration simply involves moving this code to JSF backing beans

Incremental migration● If the business logic is dispersed throughout web-

layer actions, the process can be more complicated– Good time for refactoring!

● You can either:– Migrate portions of application logic after migrating all

pages to JSF components, or – Migrate related pages and application logic at the

same time– This is possible because all of the code is running in

the same web application

Incremental migration– Even if part of the application uses JSF and part

uses another framework, the same objects can be shared

Incremental migration

● There are three layers that must be migrated to JSF:– Configuration– JSP pages– Application logic

● Artifacts roughly map to each other– A Struts forward is roughly

equivalent to a JSF navigation rule, and both are handled through configuration files

– Most Struts tags have JSF or JSTL equivalents

Full migration● More cohesive

– Application never uses two frameworks at once● More time consuming● Logical approach when you need to rewrite or

substantially update the application● Provides an opportunity to take advantage of some

of JSF's unique features, as opposed to simply porting the application

● Conceptually similar to the process of incremental migration– View, configuration, and application layers must be

converted

Full migration● Conceptually similar to the process of incremental

migration– The key difference is that no integration library is

necessary– Entire application must be migrated before all of its

functionality will be available● Well suited for frameworks for which no JSF

integration library currently exists

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

The Struts-Faces integration library

● Written by Craig McClanahan– Original author of Struts – Co-spec lead for JSF 1.0– Original author of Shale

● Primary goal of the library is to provide support for JSF’s UI components

● You can use JSF components on pages that use normal Struts features such as ActionForms, ActionForwards, and Actions

● Includes JSP custom tags, renderers, and UI components that replace existing Struts tags

● In most cases, replacing Struts tags with JSF-based equivalents is straight-forward

The Struts-Faces integration library

● You can usually leave your Struts Actions and your application and domain logic untouched

Struts-Faces integration library implementation details

● Integrates Struts support into the JSF implementation and leaving you access to the traditional Struts ActionServlet

● Struts-Faces applications can continue to process Struts requests normally, but they can also support all of the combinations of Faces and Non-Faces requests

Struts-Faces integration library implementation details

● Struts-Faces implements all four Faces Request / Response scenarios:

Struts-Faces integration library implementation details

● Struts-Faces applications have an instance of Struts’ ActionServlet and JSF’s FacesServlet running

● Faces requests result in Struts responses if the Struts-Faces <s:form> tag is used– This is accomplished by replacing JSF’s default

ActionListener implementation with a Struts-Faces ActionListener

– When a JSF ActionEvent occurs from a Struts-Faces form, the new ActionListener executes a Struts Action instead of a JSF action method

– The Struts Action is executed by a specialized RequestProcessor

Struts-Faces integration library implementation details

Installing the Struts-Faces integration library

● You can download the library from the Apache Struts web site

● The first thing you need to do is set up the proper libraries:– Add the Struts-Faces library to your application

● Single JAR: struts-faces.jar– Add the JavaServer Faces libraries to your application

● Either Apache MyFaces or Sun RI– Add the JavaServer Pages Standard Template Library

(JSTL) to your application

Installing the Struts-Faces integration library

● Add the JSF controller servlet to your web application’s deployment descriptor (WEB-INF/web.xml)– This step is required for any other JSF application

<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup></servlet>

– FacesServlet must load first– Struts ActionServlet must load later

● Either remove <load-on-startup> element from the ActionServlet configuration or change its value to 2 or higher

Installing the Struts-Faces integration library

● Add a servlet mapping for the JSF controller servlet to your web application’s deployment descriptor (WEB-INF/web.xml)– This is required for any JSF application

<servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern></servlet-mapping>

Installing the Struts-Faces integration library

● Add the Struts-Faces RequestProcessor to your Struts configuration file (WEB-INF/struts-config.xml)– If you’re not using Tiles, use the

FacesRequestProcessor class:<controller> <set-property property="processorClass" value="org.apache.struts.faces. application.FacesRequestProcessor"/></controller>

– If you are using Tiles, use the FacesTilesRequestProcessor class:<controller> <set-property property="processorClass" value="org.apache.struts.faces. application.FacesTilesRequestProcessor"/></controller>

Installing the Struts-Faces integration library

– If you’ve developed your own RequestProcessor, you’ll need to subclass the appropriate Struts-Faces RequestProcessor and register your own class instead:<controller> <set-property property="processorClass" value="org.foo.MyCustomRequestProcesor"/></controller>

Migrating Struts JSP tags● The Struts-Faces JSP custom tags are intended to

replace most of the Struts HTML and Bean custom tags

● The Struts team also advocates replacing the remaining Struts Logic and Bean tag libraries with the equivalent Java Standard Tag Library (JSTL) tags

● Some of the tags are direct replacements for Struts tags, and some are intended to be used instead of standard JSF tags

Migrating Struts JSP tags● You can import the Struts-Faces tag library with the

following directive:<%@ taglib prefix="s" uri="http://jakarta.apache.org/struts/tags-faces" %>

● Most of the Struts-Faces tags have similar names to the Struts tags

● Like standard JSF tags, the attributes accept JSF EL expressions

● Struts-Faces provides automatic support for DynaBeans and DynaActionForms in JSF value-binding expressions

Migrating Struts JSP tags● Supports a special “struts” implicit variable for use in

JSF EL expressions

Migrating Struts JSP tags● Supports a special “struts” implicit variable for use in

JSF EL expressions

Converting a simple JSP page● Main menu from original Struts example application

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %><%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><jsp:useBean id="user" scope="session" type="org.apache.struts.webapp.example.User"/><html:html> <head> <title><bean:message key="mainMenu.title"/></title> <html:base/> </head> <body bgcolor="white"> <h3><bean:message key="mainMenu.heading"/> <jsp:getProperty name="user" property="username"/> </h3> <ul> <li><html:link page="/editRegistration.do?action=Edit"> <bean:message key="mainMenu.registration"/></html:link> </li> <li><html:link forward="logoff"> <bean:message key="mainMenu.logoff"/></html:link> </li> </ul> </body></html:html>

Converting a simple JSP page● Main menu from original Struts example application

Converting a simple JSP page● Enclose all component tags in an <f:view> tag.

– Convert all tags to equivalent Struts-Faces or standard JSF component

● Use JSF HtmlPanelGrid or HtmlDataTable components for layout (optional)

● Change any ActionForwards that point to this page in struts-config.xml to use the FaceServlet prefix (/faces/). – Example:

● <forward name="success" path="/mainMenu.jsp"/> would be changed to:

● <forward name="success" path="/faces/mainMenu.jsp"/>

Converting a simple JSP page● Remove the Struts tag libraries● Remove the <jsp:useBean> tag

– JSF value-binding expressions will find the User object in any scope

● Add the JSF standard tag libraries with the following directives:<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %><%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

● Add the Struts-Faces tag library to the page with the following directive:<%@ taglib prefix="s" uri="http://jakarta.apache.org/struts/tags-faces" %>

Converting a simple JSP page● Converted main menu page

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %><%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %><%@ taglib prefix="s" uri="http://jakarta.apache.org/struts/tags-faces" %><f:view><s:html locale="true"><head> <title> <s:message key="mainMenu.title"/> </title> <s:base/> <s:stylesheet path="/stylesheet.css"/></head><body> <h:panelGrid columns="1" headerClass="list header" rowClasses="list row even,list row odd" styleClass="list"> <f:facet name="header"> <h:panelGroup> <s:message key="mainMenu.heading"/> <h:outputText value="#{user.username}"/> </h:panelGroup> </f:facet>...

Converting a simple JSP page● Converted main menu page

... <h:outputLink value="editRegistration.do" styleClass="link"> <f:param name="action" value="Edit"/> <s:message key="mainMenu.registration"/> </h:outputLink> <h:outputLink value="logoff.do" styleClass="link"> <s:message key="mainMenu.logoff"/> </h:outputLink> </h:panelGrid></body></s:html></f:view>

● New page makes full use of JSF components● Can attach JSF event listeners to components● Has identical behavior● Uses Struts Actions

Using JSF action methods and managed beans

● You can use ordinary action methods and managed beans just as you would in a pure JSF application

● To use JSF event listeners, use the standard JSF <h:form> tag instead of the Struts-Faces <s:form> tag

● You can, however,mix both Struts-enabled forms and regular JSF forms in the same view:<f:view> ... <s:form action="/hitMe"> ... <h:commandButton value="Hit me with those digits!"/> </s:form> <h:form> ... <h:commandButton value="Hit me with those digits!" action="#{myBean.hitMe}"/> </h:form></f:view>

Using JSF action methods and managed beans

● In this snippet, the top form submits to the Struts Action /hitMe, while the bottom form submits to the JSF action method myBean.hitme<f:view> ... <s:form action="/hitMe"> ... <h:commandButton value="Hit me with those digits!"/> </s:form>

<h:form> ... <h:commandButton value="Hit me with those digits!" action="#{myBean.hitMe}"/> </h:form></f:view>

Invoking Struts Actions from JSF event handlers

● You can forward control to Struts Actions from JSF event listeners (Value change listeners, validator methods, and so on) and action methods

● This technique can be used during migration– Start by simply wrapping existing Struts actions– Later, you can incrementally move the

functionality from Struts Actions to JSF actions (presumably migrating the navigation rules as well)

Invoking Struts Actions from JSF event handlers

● Example of invoking a Struts Action from a JSF action method:public String hitMe(){ FacesContext context = FacesContext.getCurrentInstance(); String url = "/hitMe.do?digits=23"; try { context.getExternalContext().dispatch(url); } catch (IOException e) { throw new FacesException(e); } finally { context.responseComplete(); } return null;}

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● Migration / integration barriers● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

JSF Future Directions

● JSF 1.2 Public Review Draft just approved● Will be part of J2EE 5.0● Theme for JSF 1.2 and JSP 2.1: Web tier alignment

– Better integration with JSTL● Unified EL● Abstract base classes for pluggable extensions ● Labels for validation error messages● Support multiple instances of the same view in

different browser windows● JSP alternatives

– Struts Shale – Facelets

Agenda

● JavaServer Faces (JSF) overview● What is Struts Shale?● When to use JSF with other frameworks● The many faces of requests and responses● Migration / integration strategies● Using the Struts-Faces integration library● Future Directions● Summary● Q & A

Adapted from JavaServer Faces in Action (Manning) http://www.jsfcentral.com

Summary● JSF is the new standard Java web framework

– Powerful UI component architecture– Basic controller functionality– Many extension points– Third-party UI component market

● Use JSF with other frameworks when:– You want to migrate– If other frameworks have required features that

JSF doesn't have● Barriers to JSF migration

– JSP views only (for now)– Skill set of current staff

Summary● JSF defines two types of requests and responses:

– Faces Requests and Responses– Non-Faces Requests and Responses

● Migration strategies– Components only– Incremental– Full

● Struts-Faces library supports first two migration strategies

Resources● From Struts to JSF White paper

– http://www.m7.com/download/FromStrutsToJSF.pdf● JSF Central

– http://www.jsfcentral.com● Sun's JSF home page

– http://java.sun.com/j2ee/javaserverfaces● Apache MyFaces open source implementation

– http://myfaces.apache.org● Struts-Faces integration library

– http://svn.apache.org/builds/jakarta-struts/nightly/struts-faces/● JSF in Action home page

– http://www.manning.com/mann● Struts Shale

– http://struts.apache.org/shale/index.html● Facelets

– https://facelets.dev.java.net/

Q&A

JavaServer Faces in Action

● Available now – Amazon– http://www.manning.com/mann

● What's inside:– Explains what JSF is, how it works, and how it

relates to existing web frameworks– Extensive examples of using all standard

components, renderers, validators, and converters– Comprehensive case study– Application design guidelines– Integration with Struts and JSTL integration– Working with JSP and other display technologies– How to create custom renderers, components,

validators, and converters– Coverage of different IDEs