There is an application scoped bean.
@Named
@ApplicationScoped
public class Bean {
@Inject
private Service service;
private Entity entity; // Getter.
// Entity is periodically fetched by EJB timers on the server side
// which when fetched notifies associated clients through WebSockets.
// Clients then update themselves by sending an AJAX request.
// All of these things collectively form a different chapter.
// Just that update() needs to be invoked, when a client sends a synchronous GET request
public Bean() {}
@PostConstruct
private void init() {
consume();
}
private void consume() {
entity = service.getEntity();
}
public void update() {
consume();
System.out.println("update called.");
}
}
This bean is accessed by a page included in the master template as follows (West.xhtml
) :
<html lang="#{localeBean.language}"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:form>
<!-- This is merely a fake attempt to show something like this is expected. -->
<ui:define name="metaData">
<f:metadata>
<f:viewAction action="{bean.update}"/>
</f:metadata>
</ui:define>
<h:outputText value="#{bean.entity.field}"/>
</h:form>
</html>
There is a false attempt to invoke the update()
method by using <f:viewAction>
from the master template which is against its semantics.
For this to function, the <f:viewAction>
needs to be repeated on individual template clients which makes it difficult to maintain, especially when something needs to be changed.
Is there any possibility to avoid <f:viewAction>
being repeated all over the place on every template client?
The master page template looks like the following. It is not required. Just assume that the above page is included using <ui:include src=".."/>
in the following master template (/WEB-INF/templates/Template.xhtml
).
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view locale="..." ...>
<ui:insert name="metaData"></ui:insert>
<h:head>
<title><ui:insert name="title">Default Title</ui:insert></title>
</h:head>
<h:body>
<h:panelGroup layout="block">
<ui:insert name="contentBar">
<!-- The file given above is included here - West.xhtml. -->
<ui:include src="/WEB-INF/template/contents/West.xhtml"/>
</ui:insert>
</h:panelGroup>
<ui:insert name="content">Default contents</ui:insert>
<!--Other content bars.-->
</h:body>
</f:view>
</html>
<f:viewAction>
needs to be placed on template clients associated something like the following.
<ui:composition template="/WEB-INF/templates/Template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:define name="title">Page Title</ui:define>
<ui:define name="metaData">
<f:metadata>
<f:viewAction action="#{bean.update}"/>
</f:metadata>
</ui:define>
<ui:define name="content">
<!--Main contents-->
</ui:define>
</ui:composition>
And so forth, <f:viewAction>
needs to be repeated on every such template client for it to do its coherent task.
Is there a way to declare <f:viewAction>
appropriately at a single place so that there is no need to repeat it on every associated template client?