SlideShare una empresa de Scribd logo
1 de 42
Descargar para leer sin conexión
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?

Más contenido relacionado

La actualidad más candente

Spring 3.x - Spring MVC
Spring 3.x - Spring MVCSpring 3.x - Spring MVC
Spring 3.x - Spring MVC
Guy Nir
 
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
 

La actualidad más candente (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 a Training: Day Four - Struts, Tiles, Renders and Faces

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
 
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Stepbystepguideforbuidlingsimplestrutsapp 090702025438-phpapp02
Rati Manandhar
 

Similar a 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
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

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?