Programatically set context variable to enable/disable bean validation - jsf

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}">

Related

How to pass argument to method in ui:repeat or c:forEach [duplicate]

I have just a question in passing parameters on backing beans method.
I would like pass an EL value between a method parameters like:
<p:selectOneMenu id="somsgroup" value="#{store_itemController.filter_sgroup}">
<f:selectItems value="#{commonDataFunctions.getItemByName('store_sgroup', 'id', 'title', '[tb:store_sgroup][fd:title]=${store_itemController.filter_group}', '[tb:store_sgroup][fd:title]', true)}"/>
</p:selectOneMenu>
it seems like ${store_itemController.filter_group} it is not translated because the method receives ${store_itemController.filter_group} just like a string.
Is there a solution?
You can indeed not nest EL expressions this way. EL expressions can only be inlined.
You can use <c:set> to create a new variable wherein the desired expression is inlined in the desired value and then reuse this variable as argument of another EL expression.
xmlns:c="http://java.sun.com/jsp/jstl/core"
...
<c:set var="filterGroup" value="[tb:store_sgroup][fd:title]=#{store_itemController.filter_group}" scope="request" />
...
<f:selectItems value="#{commonDataFunctions.getItemByName('store_sgroup', 'id', 'title', filterGroup, '[tb:store_sgroup][fd:title]', true)}"/>
I would like to suggest to use JBoss EL. If so, you need to configure as below in web.xml.
Download jar file here and reference for previous post.
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>

#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.

Composite component required="true" not respected

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)
...

JSF: UI component dynamic rebinding in a single page wihout reload. Possible?

Being inspired with the article considering the dynamic table rendering (thank you BalusC), I've finally got the exact result I wanted before here a bit earlier. That gave quite perfect results since I could control the behavior of a every single column respecting the business logic requirements. But that was pretty cool if that table was a part of an experimental "static" page where I was making some dynamic binding experiments.
Once I had to merge the ideas to the existing code (more or less stupid knowing nothing about the dynamic expressions), I've got face to face with the following problem: the dynamic binding seems to work only once during the load of the page. Ok, I thought that I was missing to separate the dynamic binding bean and the "main" page bean (controlling user actions like clicking the tree nodes by a user).
A simplified instance of my current page piece is as follows (consider you have a tree at the left and when you click a tree node, you have to get quite another data table [PrimeFaces used]):
a tree, table selector (works pretty perfect)
<p:tree value="#{tableViewsPageBean.root}" var="node" dynamic="true" cache="false"
selectionMode="single" selection="#{tableViewsPageBean.selectedNode}">
<p:ajax event="select" listener="#{tableViewsPageBean.onNodeSelect}" update=":form:scene"/>
<p:treeNode id="treeNode">
<h:outputText value="#{node}"/>
</p:treeNode>
</p:tree>
a table that's intented to be dynamically rendered once a user clicks a tree node above
<h:panelGroup id="scene">
...
<h:panelGroup binding="#{dynamicDataTableBean.dataTableGroup}"/>
</h:panelGroup>
The tableViewsPageBean is defined as a #ViewScoped bean, and the dynamicDataTableBean is a #RequestScoped bean (I should not think that it might help -- I just had an idea).
But, for me, the following code is requested only once during the page load:
public HtmlPanelGroup getDataTableGroup() { ... }
I don't know, but is it possible to force this code execution to rebind the component in the panel group mentioned above without page reload? Thanks in advance.
Sorry, my bad. I had the following in my web.xml:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
That option must be set to true. However, then I still have the problem described here.

What is the JSF behaviour, if you bind the same backing bean property to two input fields in the same form?

Is there a defined behaviour in JSF, if two input fields are bound to the same session scoped Backing Bean property.
Here is my code snippet
<h:form id="myForm">
<h:inputText id="field1" value="#{TheBackingBean.theProperty}" />
<h:inputText id="field2" value="#{TheBackingBean.theProperty}" />
<h:commandButton id="continueButton" action="#{TheBackingBean.doSomething}" />
</h:form>
My question: If field1 and field2 receive different values, what will be bound to the backing bean property? Is this even allowed?
I know this is a crude scenario. My motivation is, that we have htmlunit tests running for our application. In our JSF application we want to use a cool ajaxified custom component. This doesnt work together very well with htmlunit. So my idea was, I just put in a hidden field that binds to the same property. The unit test then fills the hidden field instead of the "real" thing.
Regards
I think this kind of code is allowed, but I am not sure of the value of theProperty after the submission. What I think is that JSF will do the following:
TheBackingBean.setTheProperty(field1.value);
TheBackingBean.setTheProperty(field2.value);
However, nothing - as far as I know - specifies the order of the setter calls. Thus, after the update values JSF phase, you will not be sure if theProperty will be equal to field1.value or field2.value.
Concerning your scenario, you say that you want to bind the same property to an inputText and an hiddenText. As the hiddenText will not submit its value, unlike the inputText, this problem will not occur. Indeed, if you have this kind of JSF code:
<h:inputText id="field1" value="#{TheBackingBean.theProperty}"/>
<h:inputHidden id="field2" value="#{TheBackingBean.theProperty}"/>
then JSF will only do:
TheBackingBean.setTheProperty(field1.value);
during the submission phase.

Resources