JSF f: viewParam does not call setter if found in template.xhtml

Maybe someone can enlighten me.

If put

<f:metadata> <f:viewParam name="test" value="#{test.value}"/> </f:metadata> 

inside the template, setter

  setValue 
never called, i.e. The preRender "call ()" method is called without first calling setter (see the sample code below for reference).

If, however, placing the metadata block inside the composition, it is invoked as expected.

Is this normal behavior, or am I doing something wrong?
Thanks so much for any ideas. Hanspeter

For reference, here is a complete sample code of the broken version :

testtemplate.xhtml

 <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <f:metadata> <f:viewParam name="test" value="#{test.value}"/> </f:metadata> <f:event type="preRenderView" listener="#{test.call}" /> <h:head> <title>Test Template</title> </h:head> <h:body> <ui:insert name="text" /> </h:body> </html> 

testcomposition.xhtml

 <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="/templates/testtemplate.xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <ui:define name="text"> some text </ui:define> </ui:composition> 

and here is the full working code example:

testtemplate.xhtml

 <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <f:event type="preRenderView" listener="#{test.call}" /> <h:head> <title>Test Template</title> </h:head> <h:body> <ui:insert name="text" /> </h:body> </html> 

testcomposition.xhtml

 <?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" template="/templates/testtemplate.xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"> <f:metadata> <f:viewParam name="test" value="#{test.value}"/> </f:metadata> <ui:define name="text"> some text </ui:define> </ui:composition> 
+6
source share
1 answer

This is by specification. It is mentioned in the <f:metadata> tag documentation :

Declare a metadata facet for this view. This must be a child of <f:view> . This tag must be in the top-level XHTML file for the given viewId or in the template client, but not in the template. The implementation should ensure that the direct child of the facet is a UIPanel, even if there is only one facet child. The implementation should set the UIPanel identifier as the value of the symbolic constant UIViewRoot.METADATA_FACET_NAME .

A simple reason is that metadata should be view-specific, not template-specific. To achieve your requirement anyway, and you cannot / do not want to place <f:metadata> inside the <ui:define> each template client, it is best to use a regular bean with @ManagedProperty .

See also:

+13
source

Source: https://habr.com/ru/post/909928/


All Articles