Beruflich Dokumente
Kultur Dokumente
Faces Architecture:
A Programmer’s Guide
Kevin Hinners
Senior Technical Analyst
FedEx Services
http://fedex.com
Session TS-3364
• Objective
• Place existing Struts application code in containment
• Implementation
• Configure the project for JSF
• Any code written for the Struts framework becomes legacy
• Action and ActionForm classes, Struts tags in JSPs
• All new development work is pure JavaServer Faces
• Provide hooks to JSF-based pages
• Write managed bean classes
• Configure managed beans, navigation rules
• Create new JSPs using JSF tags
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>jsf_core.tld</taglib-uri>
<taglib-location>
/WEB-INF/tld/jsf_core.tld
</taglib-location>
</taglib>
try {
pagers = PagerDAO.selectAll();
}
catch (SQLException e) {
logger.error("Error retrieving pager list: ", e);
}
return pagers;
}
2005 JavaOneSM Conference | Session TS-3664 | 23
Containment Strategy
Configure managed beans, navigation rules
<faces-config>
<managed-bean>
<managed-bean-name>pagerBean</managed-bean-name>
<managed-bean-class>
com.fedex.pager.bean.PagerBean
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/home.jsp</from-view-id>
<navigation-case>
<from-outcome>retrieve</from-outcome>
<to-view-id>/pagerList.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
<f:view>
<f:loadBundle var="bundle" basename="resource"/>
<html>
<head>
<title>
<h:outputText value="#{bundle['maintenance-title']}"/>
</title>
<link rel="stylesheet" type="text/css"
href="html/pager.css"/>
</head>
<body>
<%@ include file="html/header.html" %>
<h1>
<h:outputText value="#{bundle.maintenance-title}"/>
</h1>
2005 JavaOneSM Conference | Session TS-3664 | 25
Containment Strategy
Create new JSPs (Cont.)
<h:form>
<h:dataTable styleClass="dataTable"
headerClass="dataHeading"
rowClasses="dataValue"
cellspacing="2" cellpadding="5"
value="#{pagerBean.pagers}"
var="pager">
<h:column>
<h:commandLink title="Edit Pager"
value="Edit" action="edit"
actionListener="#{pagerBean.editPager}">
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.pager-type}"/>
</f:facet>
<h:outputText value="#{pager.pagerType}"/>
</h:column> SM
2005 JavaOne Conference | Session TS-3664 | 26
Containment Strategy
• Consequences
• Some ongoing knowledge of Struts required
• Both Struts Web application and JSF user interface
frameworks in use
• Complex mixture of Struts, JSF tags in JSPs possible
• Easier transition
• Small learning curve
• Some transitions between Struts and JSF difficult
• Temptation to refactor requires discipline
• Objective
• Replace all existing Struts code with JSF
• Implementation
• Configure the project for JSF
• Update domain model objects (usually not required)
• Convert ActionForms to managed beans (POJO)
• Rewrite JSP pages to use JSF core and HTML tags
• Add JSF navigation rules to faces-config.xml
• Implement methods to handle actions
...
}
...
}
2005 JavaOneSM Conference | Session TS-3664 | 31
Rewrite Strategy
Convert action forms—faces-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<html>
<head>
<title>
<bean:message key="page.pager.title"/>
</title>
<link rel="stylesheet" type="text/css"
href="html/pager.css" title="Default">
</head>
<body>
<%@ include file="html/header.html" %>
<html:form action="/viewAction">
2005 JavaOneSM Conference | Session TS-3664 | 33
Rewrite Strategy
Rewrite JSPs—home.jsp after
<%@ taglib uri="html_basic.tld" prefix="h" %>
<%@ taglib uri="jsf_core.tld" prefix="f" %>
<f:view>
<f:loadBundle var="bundle" basename="resource"/>
<html>
<head>
<title>
<h:outputText value="#{bundle['page.pager.title']}"/>
</title>
<link rel="stylesheet" type="text/css"
href="html/pager.css" title="Default">
</head>
<body>
<%@ include file="html/header.html" %>
...
return (mapping.findForward("view"));
}
2005 JavaOneSM Conference | Session TS-3664 | 37
Rewrite Strategy
Implement actions—ScheduleBean.java after
public void viewSchedule(ActionEvent event) {
...
setPager(pager);
setSchedule(schedule);
}
• Consequences
• Initial detailed knowledge of Struts
• Experience with JavaServer Faces Architecture beneficial
• Steep learning curve
• Easy to introduce new bugs
• Clean solution
• More consistent look and feel
• Custom components may be beneficial
• Objective
• Use JavaServerFaces Architecture for view components and
Struts for Controller components
• Implementation
• Configure the project for JSF
• Configure the project for Struts-Faces Integration library
• Update navigation rules
• Struts Action and ActionForm classes remain largely unchanged
• Rewrite JSPs using JSF and Struts-Faces tags
• Create managed bean classes to forward to Action classes
<f:view>
<f:loadBundle var="bundle" basename="resource"/>
<body>
<s:form action="/editLoginAction">
...
<h:panelGroup>
<h:commandButton immediate="true" action="back"
value="#{bundle['page.button.pager.back']}"/>
<h:commandButton actionListener="#{viewBean.login}"
value="#{bundle['page.button.pager.edit.login']}"/>
</h:panelGroup>
...
</s:form>
</body>
</f:view> SM
2005 JavaOne Conference | Session TS-3664 | 48
Integration Strategy
Create managed bean classes
package com.fedex.pager.bean;
try {
external.dispatch("/editLoginAction.do?action=Login");
}
catch (IOException e) {
throw new FacesException(e);
}
finally {
context.responseComplete();
}
} 2005 JavaOneSM Conference | Session TS-3664 | 49
Integration Strategy
• Consequences
• Promotes code reuse
• Leverages Struts controller-centric architecture
• Managed beans required as glue code
• Supports the use of Tiles for layout framework
• Struts and JSF knowledge required
• Integration library is not final or well-supported
• Quickest option to rewrite pages using JSF tags
• NullPointerExceptions
• Property getter returns null
• Referenced binding not found in scope
• Typos in the JSP
• NoSuchElementException
• Check managed bean and ActionForm scope
• Same page displayed when clicking button or link
• Missing navigation rule
• Missing action parameter on component