1

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>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Thomas
  • 759
  • 8
  • 15

2 Answers2

1

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.

Nicola Isotta
  • 202
  • 3
  • 10
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you BalusC for the very clear explanation including the source code reference. I really appreciate that you've created an issue in the tracker. I'd love to see this working as expected in future. – Thomas Jul 16 '14 at 08:34
  • 1
    I just fixed it for OmniFaces 2.0 (snapshot). See answer update. – BalusC Jul 16 '14 at 12:06
0

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.

Community
  • 1
  • 1
Srikanth Ganji
  • 1,127
  • 1
  • 13
  • 29
  • Thanks for your answer Srikanth. I've added the VALIDATE_EMPTY_FIELDS parameter to web.xml but it didn't work. Anyway, bean validation setup seems to be ok. Request parameters get validated as expected (e.g. `?customerId=` leads to an error message). The only case that is not working is omitting parameters completely. In this case @NotNull is not evaluated. – Thomas Jul 10 '14 at 18:57
  • I'm not worried too much about the performance overhead when using bean validation. Of course you are right in saying that reflection adds some extra cost. Anyway, JSF uses reflection in many cases (value bindings e.g). – Thomas Jul 10 '14 at 19:09