7 Replies Latest reply on Feb 25, 2008 10:45 AM by mars1412

    jsf validation vs hibernate validator

      Hi,


      This is about the required=true JSF parameter versus null/empty-checks done by Hibernate Validator (HV). This has been discussed a couple of times on the old forum, and the general conclusion has been that it's an 'error' in the JSF 1.2 implementation that hopefully will be fixed in JSF 2.0. Unfortunately I don't have the time to wait for it, so I'm trying to find a temporary solution.


      What I want to do is to perform HV-validation even though the fields that are submitted are empty. I think this should be possible by 'tricking' JSF to believe the fields have values. More specifically, this is what I have in mind:


      - When a form is submitted, do some interception before the JSF validation phase (servlet filter?).


      - If any fields in submitted forms are empty, fill them with a special token.


      - Skip to JSF validation phase; fields that have been filled with the special token validate successfully.


      - Before form values are copied over to backing bean properties, and before Hibernate Validation is triggered (by Seam), nullify all fields with the special token.


      Would this work? Any implementation suggestions appreciated :)

        • 1. Re: jsf validation vs hibernate validator

          Eirik Larsen wrote on Feb 21, 2008 04:04 PM:


          - Skip to JSF validation phase; fields that have been filled with the special token validate successfully.

          - Before form values are copied over to backing bean properties, and before Hibernate Validation is triggered (by Seam), nullify all fields with the special token.


          Wish I could edit my post :) This is what I meant to write:


          - Before form values are copied over to backing bean properties, and before Hibernate Validation is triggered (by Seam), nullify all fields with the special token.


          - Skip to JSF validation phase; fields that have been filled with the special token are validated by HV.

          • 2. Re: jsf validation vs hibernate validator

            I also thought about that and what came to my mind was to use an EL-function for the required attribute like :


            required="#{util.isThisFieldRequired(entityname, fieldname)}"



            then the util seam-components isThisFieldRequired() function would look-up the entity and the fieldname and check via reflection if the field has a @NotNull or @NotEmpty annotation (or whatever)


            in this case however you would have to set this required function for every field (and the reflection thing would cost some performance)


            but I would have the benefit, that I no longer can get into the situation, where I change a fields nullable value and then have to check/update all my pages (most of the time I forget those changes, and this is also a problem)


            I know, that's not exactly what you asked for, but what do you think of this?


            P.S. I think using special tokens is quite errorprone

            • 3. Re: jsf validation vs hibernate validator


              required="#{util.isThisFieldRequired(entityname, fieldname)}"



              Not a bad idea. It has two main issues as I see it:


              1) When you use reflection to look for validators that check if a field is null or empty, how exactly should that be done? Any number of custom validators could implement null/empty-checks. If this validator-checker method is to be of any use it would have to be configured with a list of the correct validators.


              2) How is the error message from the validators to be shown in the view? One issue with required=true is that you have to refer to the same error messages in the view as you do in the Hibernate Validator. I don't think the EL-lookup solution solves this problem.



              P.S. I think using special tokens is quite errorprone

              I agree to some extent. But think of it - you only need to define one special token for this; if you choose one that is cryptic enough, what's the probability that this will cause any trouble (famous last words..)

              • 4. Re: jsf validation vs hibernate validator

                Eirik Larsen wrote on Feb 22, 2008 06:25 AM:


                2) How is the error message from the validators to be shown in the view? One issue with required=true is that you have to refer to the same error messages in the view as you do in the Hibernate Validator. I don't think the EL-lookup solution solves this problem.


                Of course you could also set the error message the same way:


                requiredMessage="#{util.getRequiredMessage(entityname, fieldname)}"


                Issue number 1 mentioned above still applies though.

                • 5. Re: jsf validation vs hibernate validator

                  I had a look at how to impement this. The solution consists of a servlet filter and a modification of Seams ModelValidator.


                  ModelValidatorFilter:


                  @Startup
                  @Scope(ScopeType.APPLICATION)
                  @Name("modelValidatorFilter")
                  @BypassInterceptors
                  @Filter(within = "org.jboss.seam.web.ajax4jsfFilter") //not sure about the 'within'
                  public class ModelValidatorFilter extends AbstractFilter {
                  
                       @Override
                       public void doFilter(ServletRequest request, ServletResponse response,
                                 FilterChain chain) throws IOException, ServletException {
                            if (!(request instanceof HttpServletRequest)) {
                                 throw new ServletException(
                                           "This filter can only process HttpServletRequest requests");
                            }
                  
                            HttpServletRequest httpRequest = (HttpServletRequest) request;
                            HttpServletResponse httpResponse = (HttpServletResponse) response;
                            Enumeration parameterNames = httpRequest.getParameterNames();
                            while (parameterNames.hasMoreElements()) {
                                 String parameterName = (String) parameterNames.nextElement();
                                 String[] parameterValues = httpRequest
                                           .getParameterValues(parameterName);
                                 for (String parameterValue : parameterValues) {
                                      if ("".equals(parameterValue)) {
                                           parameterValues[0] = "EMPTY_VALUE";
                                      }
                                 }
                            }
                            chain.doFilter(request, response);
                       }
                  }
                  



                  Modification of ModelValidator:


                  ...
                      if (valueExpression != null) {
                           if(EMPTY_VALUE.equals(value)) value = "";
                           InvalidValue[] invalidValues;
                           try {
                                invalidValues = Validators.instance().validate( valueExpression, facesContext.getELContext(), value );
                           }
                  ...



                  I didn't test this since I didn't want to modify the Seam source. I do however think that this would be a useful feature for lots of people. Nobody likes the required="true" that JSF forces us to use.

                  • 6. Re: jsf validation vs hibernate validator

                    Eirik Larsen wrote on Feb 25, 2008 09:06 AM:

                    parameterValues[0] = "EMPTY_VALUE";


                    Did a shortcut here :)

                    • 7. Re: jsf validation vs hibernate validator

                      1) When you use reflection to look for validators that check if a field is null or empty, how exactly should that be done? Any number of custom validators could implement null/empty-checks. If this validator-checker method is to be of any use it would have to be configured with a list of the correct validators.

                      yes, you are right: I would have to hardcode all validators, which is not clean a clean solution either.
                      I would appreciate any comments/ideas from the seam team on this issue.