#NotNull Bean Validation ignored for viewParam - jsf

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.

Related

Bean validation using a custom #RequiredWhen validator and required field decorator in JSF

I have defined a custom jsr-303-Validator called #RequiredWhen which is like #NotNull but depending on some condition.
In JSF, whenever I annotate a managed bean property with #NotNull a component like PrimeFaces <p:outputLabel for="that property">, recognizes the property as required and marks it with an asterisk. Is it possible to implement or configure my custom Validator such that the asterisk is shown as well, if the condition in the #RequiredWhen-annotation becomes true? Thanks a lot.
I'm using,
Java EE 6
GlassFish 3.1.2
Mojarra 2.1.29
PrimeFaces 5.2
As far as I can see by now the answer is no: it's not possible to show the asterix by configuring or implementing the custom validator. Looking at the sources of primefaces the check for #NotNull is hardcoded and there is no kind of callback to check for other annotations.
As a first workaround we added a new bean that checks an input field for our custom annotations, eg
<p:inputText id="test" value="#{uiController.data}"
required="#{ContextValidatorDelegate.isRequired('data')}"/>
But after some closer look we removed that delegate. The condition in our custom validator is dependend on properties that the user can modify in the same dialog than the property that is validated. So our validator really is some class level validator. And thus we cannot use the required-attribute, which is processed in validation phase. We need the complete user-input in our model bean. Only after the update model phase a class level validation is meaningful.

EL expressions in Omnifaces CDN resource handler not resolved in Wildfly 9

I am playing around with new Wildfly 9.0.0.Final. After the deployment of my JSF2.2 web application, the Omnifaces2.1 CDNResourceHandler stopped resolving EL expression.
My definition in web.xml:
<context-param>
<param-name>org.omnifaces.CDN_RESOURCE_HANDLER_URLS</param-name>
<param-value>
styles:*=#{CDNResourcesBean.styles}/*
</param-value>
</context-param>
In .xhtml, style.css file exists in resources of the project structure
<h:outputStylesheet library="styles" name="style.css"/>
Generated HTML:
<link type="text/css" rel="stylesheet" href="/style.css" />
My CDNResourceBean
#Named
#RequestScoped
public class CDNResourcesBean {
public String getStyles() {
return "https://abcdef.cloudfront.net/";
}
From what I see the CDNResourceHandler is called, it replaces links but from unknown reason the El expression #{CDNResourcesBean.styles} is ignored.
How should I make it working? Is that a question of CDI configuration, Bean initialization order, CDNResourceHandler not compatible with new WF?
Technology:
Application server: Wildfly 9.0.0.Final
Omnifaces: 2.1
It's consequence of a bugfix in Weld implementation of WildFly 9. As per issues CDI-525, WELD-1941 and WFLY-4877, the CDI spec appears to be not consistent with JavaBeans specification as to default managed bean name in case the unqualified classname starts with more than two capitals. CDI spec merely stated as below in the spec, while Weld was initially following the JavaBeans specification:
The default name for a managed bean is the unqualified class name of the bean class, after converting the first character to lower case.
Weld was been put back to take it literally. The CDNResourcesBean is now registered as as #{cDNResourcesBean} instead of #{CDNResourcesBean}.
For now, if you intend to follow the JavaBeans specification, then your best bet is to explicitly specify the managed bean name.
#Named("CDNResourcesBean")
#RequestScoped
public class CDNResourcesBean {}
This problem is not related to OmniFaces.
Unrelated to the concrete problem, get rid of the double trailing slash in URL.

Exception during bean's #PostConstruct does not end up in right <error-page>

My question is quite simple (to ask). How can I create and manage my Exceptions in a JSF application?
First we have the separation from normal and Ajax requests.
Problem solved by using FullAjaxExceptionHandler by Omnifaces.
Ok, now my Ajax exceptions follow the JSF/web.xml path. Next step is to create the mappings in web.xml:
<error-page>
<exception-type>java.lang.SecurityException</exception-type>
<location>/errors/security.xhtml</location>
</error-page>
The problem then is that Exceptions are not going to match above rules as they have been wrapped by other Exception types.
Ok, Omnifaces to the rescue again with FacesExceptionFilter.
Ok, so now I can throw Exceptions from my beans, e.g.
#PostConstruct
public void init() {
throw new SecurityException("Go away!");
}
Unfortunately this won't work, because Exception is thrown during bean initialization and not when calling a method.
Omnifaces unwrap method will stop to the occurrence of aFacesException and CDI (Weld) will wrap any exceptions during Bean initialization to a FacesException (which I assume is conforming to the spec).
I could write my own Exception filter that will not stop unwrapping a FacesException, you quickly realize that you might go deeper in the stacktrace than one would like.
How can I manage Exceptions during Bean initialization?
The managed bean creation and initialization is not supposed to throw an exception in first place.
You'd better move this security checking logic elsewhere. E.g. a real security framework (container managed via JAAS/JASPIC or 3rd party like Shiro), or a servlet filter, or if you
really really want to keep it in "the JSF house", use <f:viewAction> instead.
<f:viewAction action="#{bean.init}" />
(don't forget to remove the #PostConstruct annotation)
If you're not on JSF 2.2 yet, use preRenderView event instead.
<f:event type="preRenderView" listener="#{bean.init}" />
See also:
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
Is it possible to disable f:event type="preRenderView" listener on postback?

Invoking methods with parameters by EL in JSF 1.2

I am using a datatable and for each row I have two buttons, an "Edit" and a "Delete".
I need these buttons to be read-only, i.e. disabled, if a certain condition is met for the row in question. I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Ideally what I would like it something like (the looping variable is loop and there is another bean, helper, which contains the method I would like to invoke):
<h:commandButton value="Edit"
disabled="#{helper.isEditable(loop.id)}" />
In this case it does not make semantic sense to add an isEditable attribute to the bean and it is not practical to create a wrapper Object around the bean.
Thanks in advance.
I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Passing parameters to method calls is not specific to JSF 2. It is specific to EL 2.2, which is in turn part of JSP 2.2 / Servlet 3.0 / Java EE 6. JSF 2 just happens to be part of Java EE 6 as well. In other words, if you deploy your JSF 1.2 web application to a Servlet 3.0 compatible container like Tomcat 7, Glassfish 3, etc and your web.xml is declared conform Servlet 3.0 spec version, then it'll just work out the box for JSF 1.x as well.
If you're however still targeting a container of an older Servlet version, then you need to supply a different EL implementation which supports invoking methods with arguments. One of those implementations is JBoss-EL which you can install by just dropping the jboss-el.jar file in /WEB-INF/lib of your webapp and adding the following context parameter to the web.xml. Here's a Mojarra-specific example (Mojarra is the codename of JSF RI):
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
If you're using MyFaces as JSF implementation, you need the following context parameter instead:
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
See also:
Invoke direct methods or methods with arguments / variables / parameters in EL

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.

Resources