Composite component required="true" not respected - jsf

In the composite:interface I have defined an attribute like this:
<composite:attribute name="myAttribute" required="true"/>
Now when I use my composite component like this, without defining any attributes:
<myTag:myCC/>
I would expect an error to occur. It doesn't. What could I possibly be missing?

It will only occur if your JSF project stage is set to Development as follows in web.xml:
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
It defaults to Production. Don't be surprised if you start to see several other errors/warnings related to "development mistakes" after setting the above context parameter.
In your specific case you should get an exception during opening the page something like this when you omit the required attribute:
javax.faces.view.facelets.TagException: /test.xhtml #22,19 <my:composite> The following attribute(s) are required, but no values have been supplied for them: foo.
at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:232)
at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:95)
...

Related

How to get a different error page for different PROJECT_STAGE in JSF

I want to show detail exception along with stack trace on error page if the project stage is development
web.xml entry -
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
else if Project stage is Production then I want to show a custom message to user.
web.xml entry-
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
Is there any way to achieve this?
The JSF project stage is available by Application#getProjectStage(). The JSF application is in turn available by FacesContext#getApplication(). The JSF context is in EL available by #{facesContext}.
So, this should do in the error page:
<c:choose>
<c:when test="#{facesContext.application.projectStage eq 'Development'}">
<!-- Print stack trace here -->
</c:when>
<c:otherwise>
<!-- Print custom message here -->
</c:otherwise>
</c:choose>

#NotNull Bean Validation ignored for viewParam

Problem
I'm trying to validate a mandatory GET request parameter.
In the view I've added a corresponding viewParam tag.
<f:metadata>
<f:viewParam name="customerId" value="#{customerDetailBean.customerId}"/>
</f:metadata>
And my CDI bean looks like this
#Model
public class CustomerDetailBean {
#NotNull
private Integer customerId;
public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
}
When I use the following request, validation works fine and the expected validation message is displayed.
http://localhost:8080/getsupport/customerdetail.jsf?customerId=
However, when I change the request by removing the parameter customerId, validation is skipped and no message is shown.
http://localhost:8080/getsupport/customerdetail.jsf
Is there a way to make it work as expected?
Workaround
I've changed my viewParam declaration to
<f:metadata>
<f:viewParam name="customerId" value="#{customerDetailBean.customerId}" required="true" />
</f:metadata>
That updated version works fine with the second request. Anyway I would prefer to use bean validation.
My setup
Mojarra JSF 2.2.7
Weld 2.2.1.Final
Hibernate Validator 5.1.1.Final
Tomcat 7.0.54
web.xml
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
This is, unfortunately, "working as designed". All validation is skipped when nothing's been submitted. Only the <f:viewParam required> has special treatment. It's also considered when nothing's been submitted. See also UIViewParameter#processValidators() javadoc and source code.
In the Mojarra issue tracker I can only find issue 3058 as a related issue, whereby the <f:validateRequired> isn't being considered. This is technically actually exactly the same problem as you're facing with #NotNull. I've created issue 3339 on this.
In the meanwhile, your best bet is falling back to required="true". A custom component can also, but as far as I see this isn't going to be trivial.
Update: after all, the fix is relatively easy and has been implemented in OmniFaces <o:viewParam> in the current 2.0 snapshot release.
Prior to JSF 2.0, validation was simply not run at all on fields whose values were
empty or null. JSF 2.0 changes this default behavior slightly. If the JSF runtime is executing in
an environment that supports bean validation, empty fields are validated by default. Otherwise,
the behavior is the same as it was prior to JSF 2.0: empty fields are not validated.
Since Tomcat(& Jetty) is not a J2EE compliant server bean validation is not enabled by default. That is the reason why your validation is skipped.
To force JSF to validate empty fields, add this to your web.xml file:
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>true</param-value>
</context-param>
The Bean validation(JSR 303) can be configured on non j2ee compliant server with minimal configuartion(I have never configured this :)). In some way you have enabled bean validation and you have not above context param then jsf runtime would consider it as true and validate empty and null fields for validation.
But I suggest to use required attribute which is suggested experts for performance because using annotations invove reflections. So we could avoid for atleast in one case.
And ensure context param javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR is not set to true in web.xml.
To have a look at list of these parameters see
Overview of all JSF-related web.xml context parameter names and values
Hope this helps.

Programatically set context variable to enable/disable bean validation

In my web.xml, I have this configuration entry:
<context-param>
<param-name>javax.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR</param-name>
<param-value>true</param-value>
</context-param>
However, I don't want it to be always true.
I want to set it true or false in my managed bean, depending on the situation.
Is that possible?
No, that's the wrong way of solving the concrete problem. For that, the <f:validateBean> tag should actually be used instead.
You can use it on a per-view or per-form basis, most self-documenting would be to just wrap it around the <h:form>. The <h:form> in turn can be just in a template client (and the <f:validateBean> thus in the master template).
<f:validateBean disabled="true">
<h:form>
</h:form>
</f:validateBean>
You can even use EL in there.
<f:validateBean disabled="#{settings.beanValidationDisabled}">

How to produce javax.faces.ViewState hidden field without 'id' and 'autocomplete' attributes

This is what I have in the output HTML document (produced by JSF 2.0/Mojarra 2.0.3):
<input type="hidden" name="javax.faces.ViewState"
id="javax.faces.ViewState" value="4267906931114993858:-6309146738430577631"
autocomplete="off" />
My document should be XHTML 1.1 compliant, where attribute autocomplete is not valid and id attribute is duplicated over all forms. How to instruct JSF to produce everything strictly compliant to XHTML?
See.
<context-param>
<param-name>com.sun.faces.autoCompleteOffOnViewState</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.enableViewStateIdRendering</param-name>
<param-value>false</param-value>
</context-param>
The non unique use if the ID javax.faces.ViewState is a bug that appears Oracle will not fix. They have closed these tickets. No workaround.
How to instruct JSF to produce
everything strictly compliant to
XHTML?
That's not a matter of "instructing" the JSF implementation with a simple flag. It's something that has to be continuously checked and thus only possible when it's considered important by the project. XHTML strict imposes a lot of restrictions and is probably therefore generally not considered worth supporting - see this bug. Note also that any component library you use also has to support it.
You'll have a lot more luck with XHTML 1.0 Transitional - I can confirm that MyFaces does produce valid XHTML 1.0 Transitional (once you set the context param org.apache.myfaces.RENDER_VIEWSTATE_ID to false).
There is a solution to this problem, it was created in version 1.2_14 of JSF. I think the problem is related to the way that Firefox operates during the reset event (input type=reset) on hidden fields. There is a problem where the client viewState that is on a hidden field gets an inconsistent state. The solution for this problem was disabled the auto-complete in a strict way (and this is not XHTML compliant). The most interesting thing is that until 1.2_14 almost everybody lived with this potential error. So the JSF-RI implementation (Mojarra project) allowed a developer to disable this option using a parameter that you can edit in your web.xml, and this auto complete won't print anymore.
<context-param>
<description>Put your description here :)</description>
<param-name>com.sun.faces.autoCompleteOffOnViewState</param-name>
<param-value>false</param-value>
</context-param>
It is really difficult to produce valid XHTML pages with component based frameworks like JSF, but at least a solution exists for this problem.
It's not a good idea to disable autocomplete="off" for ViewState hidden input fields, because then Firefox doesn't refresh the ViewState-Id on page refresh. This causes unusable JSF forms and functionalities.
See this post for details.

Lost RichFaces skin when rendering through rich:panel and a4j:include

I have an h:selectOneMenu and an a4j:commandButton, the latter of which reRenders a component called content which looks like this:
<rich:panel id="content">
<a4j:include viewId="#{MyBacking.viewId}" />
</rich:panel>
When the response is rendered and the component loads the content of the new JSP page, the tabs contained in that page use a skin that is different from the rest of the app (I think default blue).
I've noticed that after the included code is loaded, if I hit refresh, although this causes the bean to reissue the page contents, the skin is properly assigned.
My web xml says:
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>glassX</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING</param-name>
<param-value>enable</param-value>
</context-param>
<context-param>
<param-name>org.richfaces.CONTROL_SKINNING_CLASSES</param-name>
<param-value>enable</param-value>
</context-param>
Is this effect because RichFaces is in some way not in control of the rendering of the tabs at this point?
How can I ensure the tabs conform to the skin? All the documentation is relating to overriding a skin, and I'd rather not have to override and skin with the skin that it should already have.
Thanks
I am not sure if it will solve your problem, however you can try to force Richfaces to avoid using the default skin by setting a specific web.xml parameter:
<context-param>
<param-name>org.richfaces.LoadStyleStrategy</param-name>
<param-value>ALL</param-value>
</context-param>
You can find more details about this property here.
edited, to set the correct param-value, as stated in the comments.
I've just noticed I'd included a styleClass parameter - and because the jsp is now included didn't have access to the css facet reference.

Resources