SlideShare a Scribd company logo
Presentation Layer

Sérgio Silva

October 2013
Fenix Architecture
Application Container (Tomcat, Jetty)

JSPs
renderers

Faces
Jersey
(REST API)
Domain
Model

Struts

Fenix Framework
(STM)

MYSQL
Today
Application Container (Tomcat, Jetty)

JSPs
renderers

Faces
Jersey
(REST API)
Domain
Model

Struts

Fenix Framework
(STM)

MYSQL
Struts
Control 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/
Struts
Control Layer
Struts
Control Layer
Struts Dispatching
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705
Struts Dispatching
Module
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

Semantic division in modules
● struts-publico.xml
● .do maps to Struts Servlet (JavaServlet API)
○ src/main/resources/web.xml
Struts Dispatching
Mapping
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

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">
Struts Dispatching
Mapping
fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705

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

each action is module aware

●

usually extends FenixDispatchAction (check outline on eclipse)
○

helper methods
■
■

redirect

■

getLoggedPerson

■

●

getFromRequest

getDomainObject(request,parameter)

method execute runs always
DEMO
Struts @ Fenix
Action
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
Wrapping Up
JSPs
Presentation Layer
Struts
Presentation 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
Struts @ Fenix
Forwards
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 @ Fenix
Forwards
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 @ Fenix
Forwards
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 @ Fenix
Forwards (Deprecated)
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 @ Fenix
Forwards (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"/>
JSPs
● JavaServer Pages (JSP)
● create dynamically generated web pages
based on HTML
● HTML with behaviour
DEMO
publico/executionCourse/marks.jsp
JSPs
without renderers
● publico/executionCourse/marks.jsp
<logic:iterate id="evaluation" name="executionCourse property="orderedAssociatedEvaluations
"
">

● 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<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"
);
}
JSPs
without renderers
● publico/executionCourse/marks.jsp
<logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations">

● 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<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
JSPs
without 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/
JSPs
Renderers
● integration with domain model and fenixframework
● our taglib <fr:*>
○ fr:view - display domain objects
○ fr:create - create domain objects
○ fr:edit - edit domain objects

● renderers-config.xml
○ All renderers definitions
JSPs
Renderers
● 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
JSPs
renderers-config.xml

● 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>
JSPs
Renderers
● 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>
JSPs
Renderers
● 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>
JSPs
Renderers
JSPs
Renderers
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
● 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
(inline) 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>
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
JavaServer Faces
https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474
JavaServer Faces
https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474

●

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</ anaged-bean-name>
m
<managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</
managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

DEMO
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?

More Related Content

What's hot

Paging Like A Pro
Paging Like A ProPaging Like A Pro
Paging Like A Pro
Gabor Varadi
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
Jordan Silva
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Michael Miles
 
Reactive state management with Jetpack Components
Reactive state management with Jetpack ComponentsReactive state management with Jetpack Components
Reactive state management with Jetpack Components
Gabor Varadi
 
Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
Guy Nir
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San Diego
Maxime Najim
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
Michael Miles
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applications
Gabor Varadi
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
Sergey Bolshchikov
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
Ben Lin
 
Simplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-Stack
Gabor Varadi
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
Gabor Varadi
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
NAVER Engineering
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
JS Belgrade
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback Commands
Michael Miles
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
Visual Engineering
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5
Tuna Tore
 

What's hot (17)

Paging Like A Pro
Paging Like A ProPaging Like A Pro
Paging Like A Pro
 
Spring MVC Annotations
Spring MVC AnnotationsSpring MVC Annotations
Spring MVC Annotations
 
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commandsDrupal8Day: Demystifying Drupal 8 Ajax Callback commands
Drupal8Day: Demystifying Drupal 8 Ajax Callback commands
 
Reactive state management with Jetpack Components
Reactive state management with Jetpack ComponentsReactive state management with Jetpack Components
Reactive state management with Jetpack Components
 
Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
 
Hastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San DiegoHastening React SSR - Web Performance San Diego
Hastening React SSR - Web Performance San Diego
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
 
State management in android applications
State management in android applicationsState management in android applications
State management in android applications
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Heroku pop-behind-the-sense
Heroku pop-behind-the-senseHeroku pop-behind-the-sense
Heroku pop-behind-the-sense
 
Simplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-Stack
 
Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback Commands
 
Workshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native Side
 
Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5Java Spring MVC Framework with AngularJS by Google and HTML5
Java Spring MVC Framework with AngularJS by Google and HTML5
 

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

Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
Jennifer Bourey
 
Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)
DSBW 2011/2002 - Carles Farré - Barcelona Tech
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
Aaron Stannard
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
pootsbook
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
Josué Neis
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
How to React Native
How to React NativeHow to React Native
How to React Native
Dmitry Ulyanov
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
scalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
Ngoc Dao
 
Android best practices
Android best practicesAndroid best practices
Android best practices
Jose Manuel Ortega Candel
 
Struts Intro
Struts IntroStruts Intro
Struts Intro
Syed Shahul
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
Skills Matter
 
Introduction to Struts
Introduction to StrutsIntroduction to Struts
Introduction to Struts
elliando dias
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Provectus
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
Ron Reiter
 
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Rati Manandhar
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementation
aurelianaur
 
Spine.js
Spine.jsSpine.js
Spine.js
wearefractal
 

Similar to Training: Day Four - Struts, Tiles, Renders and Faces (20)

Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)Unit 07: Design Patterns and Frameworks (3/3)
Unit 07: Design Patterns and Frameworks (3/3)
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
Struts Intro
Struts IntroStruts Intro
Struts Intro
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Primefaces Nextgen Lju
Primefaces Nextgen LjuPrimefaces Nextgen Lju
Primefaces Nextgen Lju
 
Introduction to Struts
Introduction to StrutsIntroduction to Struts
Introduction to Struts
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
 
Writing HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAEWriting HTML5 Web Apps using Backbone.js and GAE
Writing HTML5 Web Apps using Backbone.js and GAE
 
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
 
We sport architecture_implementation
We sport architecture_implementationWe sport architecture_implementation
We sport architecture_implementation
 
Spine.js
Spine.jsSpine.js
Spine.js
 

Recently uploaded

Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Jeffrey Haguewood
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
innovationoecd
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
Postman
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
Chart Kalyan
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
David Brossard
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
Edge AI and Vision Alliance
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
名前 です男
 

Recently uploaded (20)

Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
Salesforce Integration for Bonterra Impact Management (fka Social Solutions A...
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Presentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of GermanyPresentation of the OECD Artificial Intelligence Review of Germany
Presentation of the OECD Artificial Intelligence Review of Germany
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdfHow to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
How to Interpret Trends in the Kalyan Rajdhani Mix Chart.pdf
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
OpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - AuthorizationOpenID AuthZEN Interop Read Out - Authorization
OpenID AuthZEN Interop Read Out - Authorization
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
“Building and Scaling AI Applications with the Nx AI Manager,” a Presentation...
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
みなさんこんにちはこれ何文字まで入るの?40文字以下不可とか本当に意味わからないけどこれ限界文字数書いてないからマジでやばい文字数いけるんじゃないの?えこ...
 

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

  • 2. Fenix Architecture Application Container (Tomcat, Jetty) JSPs renderers Faces Jersey (REST API) Domain Model Struts Fenix Framework (STM) MYSQL
  • 3. Today Application Container (Tomcat, Jetty) JSPs renderers Faces Jersey (REST API) Domain Model Struts Fenix Framework (STM) MYSQL
  • 4. Struts Control 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/
  • 8. Struts Dispatching Module fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 Semantic division in modules ● struts-publico.xml ● .do maps to Struts Servlet (JavaServlet API) ○ src/main/resources/web.xml
  • 9. Struts Dispatching Mapping fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 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">
  • 10. Struts Dispatching Mapping fenix.ist.utl.pt/publico/executionCourse.do?method=marks&executionCourseID=1610612925705 Mapping between path and action ● Action Class ( ExecutionCourseDA.java) ● each action is module aware ● usually extends FenixDispatchAction (check outline on eclipse) ○ helper methods ■ ■ redirect ■ getLoggedPerson ■ ● getFromRequest getDomainObject(request,parameter) method execute runs always DEMO
  • 11. Struts @ Fenix Action 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
  • 14. Struts Presentation 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
  • 15. Struts @ Fenix Forwards 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" ); }
  • 16. Struts @ Fenix Forwards 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(..) ?
  • 17. Struts @ Fenix Forwards 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
  • 18. Struts @ Fenix Forwards (Deprecated) 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
  • 19. Struts @ Fenix Forwards (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"/>
  • 20. JSPs ● JavaServer Pages (JSP) ● create dynamically generated web pages based on HTML ● HTML with behaviour DEMO publico/executionCourse/marks.jsp
  • 21. JSPs without renderers ● publico/executionCourse/marks.jsp <logic:iterate id="evaluation" name="executionCourse property="orderedAssociatedEvaluations " "> ● 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<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" ); }
  • 22. JSPs without renderers ● publico/executionCourse/marks.jsp <logic:iterate id="evaluation" name="executionCourse" property="orderedAssociatedEvaluations"> ● 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<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
  • 23. JSPs without 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/
  • 24. JSPs Renderers ● integration with domain model and fenixframework ● our taglib <fr:*> ○ fr:view - display domain objects ○ fr:create - create domain objects ○ fr:edit - edit domain objects ● renderers-config.xml ○ All renderers definitions
  • 25. JSPs Renderers ● 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
  • 26. JSPs renderers-config.xml ● 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>
  • 27. JSPs Renderers ● 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>
  • 28. JSPs Renderers ● 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>
  • 31. 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>
  • 32. 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>
  • 33. 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
  • 34. 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
  • 35. Renderers (inline) 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>
  • 36. 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>
  • 37. 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"
  • 38. JavaServer Faces ● JavaServer Faces ○ version 1.1 ● component-based user interfaces for web apps ● servlet mapping *.faces ● faces-config.xml
  • 40. JavaServer Faces https://fenix.ist.utl.pt/publico/degreeSite/viewCurricularCourse.faces?degreeID=2761663971474 ● 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</ anaged-bean-name> m <managed-bean-class>n.s.f.p.b.m.c.ManagerCurricularCourseManagementBackingBean</ managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> DEMO
  • 41. 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
  • 42. Q&A?