Training: Day Four - Struts, Tiles, Renders and Faces

Post on 27-May-2015

287 views 0 download

Tags:

description

This is the fourth in our four part training sessions introducing FenixEdu development for new collaborators. In this last session, we introduce our two presentation frameworks present in fenix, Struts and Faces, the presentation plugin Tiles and our rendering library Renders

Transcript of Training: Day Four - Struts, Tiles, Renders and Faces

Presentation Layer

Sérgio Silva October 2013

Fenix Architecture

MYSQL

Application Container (Tomcat, Jetty)

Fenix Framework(STM)

DomainModel

JSPsrenderers

Struts

Faces

Jersey(REST API)

Today

MYSQL

Application Container (Tomcat, Jetty)

Fenix Framework(STM)

DomainModel

JSPsrenderers

Struts

Faces

Jersey(REST API)

StrutsControl Layer

● open-source web application framework

● uses and extends the Java Servlet API

● model–view–controller (MVC) architecture

● version 1.2.7

● http://struts.apache.org/release/1.2.x/

StrutsControl Layer

StrutsControl Layer

Struts Dispatching

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Struts DispatchingModule

Semantic division in modules

● struts-publico.xml

● .do maps to Struts Servlet (JavaServlet API)

○ src/main/resources/web.xml

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Struts DispatchingMapping

Mapping between path and action

● The path is a string

○ “/executionCourse”

● Where is the mapping ?

○ Mapping with annotations (what you should use)

@Mapping(module="publico" path="/executionCourse")

○ struts-publico.xml (read-only, don’t create things here)<action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse">

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Struts DispatchingMapping

Mapping between path and action● Action Class ( ExecutionCourseDA.java)

● each action is module aware

● usually extends FenixDispatchAction (check outline on eclipse)

○ helper methods■ getFromRequest

■ redirect

■ getLoggedPerson

■ getDomainObject(request,parameter)

● method execute runs always

DEMO

fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● Parameters○ get values on query string

● Attributes○ get or set state on request

Struts @ FenixActionfenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

StrutsWrapping Up

JSPsPresentation Layer

StrutsPresentation Layer

● Tiles○ templating system○ create a common look and feel for a web application○ create reusable view components○ bridge to JSPs○ module aware

● tiles-<module>-definitions.xml○ template definitions

● tiles-<module>-pages-definitions.xml○ fill in the template

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

Struts @ FenixForwards

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● What is mapping.findForward(..) ?

Struts @ FenixForwards

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● Forwards annotation (what you should use)@Forwards({ @Forward(name = "execution-course-marks", path = "/publico/executionCourse/marks.jsp") })public class ExecutionCourseDA extends FenixDispatchAction { … }

● name - forward name● path - logic name for tiles

Struts @ FenixForwards

ExecutionCourseDA.java

public ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● struts-publico.xml<action type="n.s.f.p.A.p.ExecutionCourseDA" parameter="method" path="/executionCourse"> <forward path="execution-course-marks" name="execution-course-marks"></forward> …………………………………………………</action>

● name - forward name● path - logic name for tiles

Struts @ FenixForwards (Deprecated)

● tiles-public-definitions.xml<definition name="execution-course-marks" extends="definition.public.executionCourse"> <put name="body" value="/publico/executionCourse/marks.jsp"/></definition>

● tiles-public-pages-definitions.xml<definition name="definition.public.executionCourse" page="/layout/istLayout.jsp"> <put name="title" value="/commons/functionalities/courseTitle.jsp" /> <put name="hideLanguage" value="true"/> <put name="symbols_row" value="/publico/degreeSite/symbolsRow.jsp" /> <put name="profile_navigation" value="/publico/degreeSite/profileNavigation.jsp" /> <put name="main_navigation" value="/publico/executionCourse/mainNavigation.jsp" /> <put name="body_header" value="/publico/executionCourse/executionCourseHeader.jsp" /> <put name="body" value="/commons/blank.jsp" /> <put name="footer" value="/publico/degreeSite/footer.jsp" /> <put name="rss" value="/messaging/announcements/rssHeader.jsp"/> <put name="keywords" value="/messaging/announcements/keywordsHeader.jsp"/></definition>

● istLayout.jsp<tiles:insert attribute="body" ignore="true"/><tiles:insert attribute="footer" ignore="true"/>

Struts @ FenixForwards (Deprecated)

JSPs

● JavaServer Pages (JSP)

● create dynamically generated web pages

based on HTML

● HTML with behaviour

DEMO

publico/executionCourse/marks.jsp

● publico/executionCourse/marks.jsp

<logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations">

● ExecutionCourseDA.javapublic ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

JSPswithout renderers

● publico/executionCourse/marks.jsp

<logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations">

● ExecutionCourseDA.javapublic ActionForward marks(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { final String executionCourseOID = request.getParameter("executionCourseID"); final ExecutionCourse executionCourse = FenixFramework.getDomainObject(executionCourseOID); Map<Attends, Map<Evaluation, Mark>> attendsMap = getAttendsMap(executionCourse); request.setAttribute("executionCourse", executionCourse); request.setAttribute("attendsMap", attendsMap); request.setAttribute("dont-cache-pages-in-search-engines", Boolean.TRUE); return mapping.findForward("execution-course-marks");}

● name - get from request attribute or parameter with that name● property - get property from object

○ executionCourse.getOrderedAssociatedEvaluations ()

● uses Java Bean conventions● id - defines bean in jsp scope

JSPswithout renderers

● simple bean example

<h3><bean:write name="executionCourse" property="name"></h3>

● executionCourse.getName()

● Tag libs○ <bean:*>○ <logic:*>○ <html:*>○ http://struts.apache.org/release/1.2.x/userGuide/

JSPswithout renderers

● integration with domain model and fenix-

framework

● our taglib <fr:*>○ fr:view - display domain objects

○ fr:create - create domain objects

○ fr:edit - edit domain objects

● renderers-config.xml

○ All renderers definitions

JSPsRenderers

● What is a renderer ?○ java class used to produce HTML○ Properties

■ layout● logical name for renderer definition

■ mode ● input● output

■ class● rendered type

○ String○ ExecutionCourse○ int

■ properties● render specific properties

JSPsRenderers

● output renderer

<renderer type="java.util.Collection" layout="contact-list" class="n.s.f.p.r.ContactListRenderer"> <property name="bundle" value="APPLICATION_RESOURCES"/> <property name="defaultLabel" value="label.partyContacts.defaultContact"/></renderer>

● input renderer<renderer mode="input" type="j.u.Collection" layout="option-select" class="p.i.fr.InputCheckBoxListRenderer"> <property name="eachClasses" value="dinline" /></renderer>

JSPsrenderers-config.xml

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● renderers-config.xml

<renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer"> <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/></renderer>

JSPsRenderers

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● renderers-config.xml

<renderer type="java.util.Collection" layout="tabular" class="p.i.f.r.CollectionRenderer"> <property name="groupLinks" value="true"/> <property name="linkGroupSeparator" value=", "/></renderer>

JSPsRenderers

JSPsRenderers

JSPsRenderers

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(reusable) Schemas

● manageApplications.jsp

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(reusable) Schemas

● Schemas

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● specify how object’s slots are rendered

● schemas-config.xml

● *-schemas.xml

○ logical separation

Renderers(reusable) Schemas

● personnelSection-schemas.xml

<schema name="oauthapps.view.apps" type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <slot name="name" key="oauthapps.label.app.name" /> <slot name="description" layout="longText" key="oauthapps.label.app.description"/> <slot name="scopes" layout="flowLayout"> <property name="eachLayout" value="values"></property> <property name="eachSchema" value="oauthapps.view.scope.name"></property> <property name="htmlSeparator" value=", "></property> </slot> <slot name="siteUrl" key="oauthapps.label.app.site.url" /></schema>

● name ○ unique identifier

● type○ schema target type

● slot○ object slot to render

Renderers(reusable) Schemas

<fr:view name="appsOwned" schema="oauthapps.view.apps"> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(inline) Schemas

<fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <fr:slot name="name" key="oauthapps.label.app.name" /> <fr:slot name="description" layout="longText" key="oauthapps.label.app.description"/> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name"></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

Renderers(inline) Schemas

Resource Bundles

<fr:view name="appsOwned"> <fr:schema type="net.sourceforge.fenixedu.domain.ExternalApplication" bundle="APPLICATION_RESOURCES"> <fr:slot name="name" key="oauthapps.label.app.name" /> <fr:slot name="description" layout="longText" key="oauthapps.label.app.description"/> <fr:slot name="scopes" layout="flowLayout"> <fr:property name="eachLayout" value="values"></property> <fr:property name="eachSchema" value="oauthapps.view.scope.name"></property> <fr:property name="htmlSeparator" value=", "></property> </fr:slot> <fr:slot name="siteUrl" key="oauthapps.label.app.site.url" /> </fr:schema> <fr:layout name="tabular"> <fr:property name="classes" value="tstyle4 thcenter thcenter"/> <fr:property name="columnClasses" value="tdcenter, tdcenter, ..."/> </fr:layout></fr:view>

● src/main/resources/resources/ApplicationResources_pt.properties○ oauthapps.label.app.name="Nome Aplicação"

● src/main/resources/resources/ApplicationResources_en.properties○ oauthapps.label.app.name="Application Name"

JavaServer Faces

● JavaServer Faces○ version 1.1

● component-based user interfaces for web

apps

● servlet mapping *.faces

● faces-config.xml

https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

JavaServer Faces

● publico/degreeSite/viewCurricularCourse.jsp

<h:outputFormat value="<h1>#{CurricularCourseManagement.degreePresentationName}</h1>" escape="false"/>

● Backing Bean

○ name - CurricularCourseManagement

● faces-config.xml

<managed-bean> <description>ManagerCurricularCourseManagementBackingBean</description> <managed-bean-name>ManagerCurricularCourseManagement</managed-bean-name> <managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope></managed-bean>

DEMO

https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

JavaServer Faces

Golden Rules

● don’t create stuff in struts-*.xml○ use annotations

■ @Mapping■ @Forwards

● @Forward

● renderers-config.xml○ read-only (unless you are going to create a new renderer)

● read renderers docs○ Administrador > Frameworks > Renderers > Exemplos Renderers

● install resource bundle editor○ https://fenix-ashes.ist.utl.pt/fenixWiki/I18NConventions

Q & A ?