8

There are two problems:

1.Sping/MVC use hibernate validater, Custom validater how to show message? like: Cross field validation with Hibernate Validator (JSR 303)

@FieldMatch.List({
    @FieldMatch(fieldName="password",verifyName="passwordVerify",message="password confirm valid!", groups={Default.class})
})
@ScriptAssert(lang="javascript",script="_this.name.equals(_this.verifyCode)")
public class LoginForm {...}

How to show the message in jsp with resource property file?

NotEmpty.loginForm.name="username can not be empty!" NotEmpty.loginForm.password="password can not be empty!"

2. I want to use group validater with spring mvc, like one userform for login and register

    @FieldMatch.List({
    @FieldMatch(fieldName="password",verifyName="passwordVerify",message="password confirm valid!", groups={Default.class})
})@ScriptAssert(lang="javascript",script="_this.name.equals(_this.verifyCode)",groups={Default.class,LoginChecks.class,RegisterChecks.class})
public class LoginForm {
    @NotEmpty(groups={Default.class,LoginChecks.class,RegisterChecks.class})
    @Size(min=3,max=10,groups={LoginChecks.class,RegisterChecks.class})
    private String name;

    @NotEmpty(groups={Default.class,LoginChecks.class,RegisterChecks.class})
    @Size(max=16,min=5,groups={LoginChecks.class,RegisterChecks.class})
    private String password;

    private String passwordVerify;

    @Email(groups={Default.class,LoginChecks.class,RegisterChecks.class})
    private String email;

    private String emailVerify;
...
}

Controller parameter annotation is @valid, any annotation support group validater by group?

First post :)

Community
  • 1
  • 1
hidehai
  • 143
  • 1
  • 7

4 Answers4

3

Update:

Spring 3.1 provides the @Validated annotation which you can use as a drop-in replacement for @Valid, and it accepts groups. If you are using Spring 3.0.x You can still use the code in this answer.

Original Answer:

This is definitely a problem. Since the @Valid annotation doesn't support groups, you'll have to perform the validation yourself. Here is the method we wrote to perform the validation and map the errors to the correct path in the BindingResult. It'll be a good day when we get an @Valid annotation that accepts groups.

 /**
 * Test validity of an object against some number of validation groups, or
 * Default if no groups are specified.
 *
 * @param result Errors object for holding validation errors for use in
 *            Spring form taglib. Any violations encountered will be added
 *            to this errors object.
 * @param o Object to be validated
 * @param classes Validation groups to be used in validation
 * @return true if the object is valid, false otherwise.
 */
private boolean isValid( Errors result, Object o, Class<?>... classes )
{
    if ( classes == null || classes.length == 0 || classes[0] == null )
    {
        classes = new Class<?>[] { Default.class };
    }
    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    Set<ConstraintViolation<Object>> violations = validator.validate( o, classes );
    for ( ConstraintViolation<Object> v : violations )
    {
        Path path = v.getPropertyPath();
        String propertyName = "";
        if ( path != null )
        {
            for ( Node n : path )
            {
                propertyName += n.getName() + ".";
            }
            propertyName = propertyName.substring( 0, propertyName.length()-1 );
        }
        String constraintName = v.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName();
        if ( propertyName == null || "".equals(  propertyName  ))
        {
            result.reject( constraintName, v.getMessage());
        }
        else
        {
            result.rejectValue( propertyName, constraintName, v.getMessage() );
        }
    }
    return violations.size() == 0;
}

I copied this source from my blog entry regarding our solution. http://digitaljoel.nerd-herders.com/2010/12/28/spring-mvc-and-jsr-303-validation-groups/

digitaljoel
  • 26,265
  • 15
  • 89
  • 115
  • Great work! I could do the job in my application. Thank a lot. – Tiny Aug 05 '12 at 11:26
  • 1
    Thanks Tiny. One thing to note is that Spring provided the @Validated annotation which allows for using groups without any of this stuff. It's a much better solution if you can use Spring 3.1 – digitaljoel Aug 06 '12 at 03:39
  • I also read about that in your blog but I'm using the spring version 3.0.2 and consequently, I have to sick to this solution right now. Thanks a lot once again. I really appreciate *your work* a lot. – Tiny Aug 06 '12 at 19:03
1

As of Spring 3.1 onwards, you can achieve group based validation by using Spring's @Validated as follows:

@RequestMapping
public String doLogin(@Validated({LoginChecks.class}) LoginForm) {
    // ...
}

@Validated is a substitute for @Valid.

Muel
  • 4,309
  • 1
  • 23
  • 32
1

Controller parameter annotation is @valid, any annotation support group validater by group?

It is possible now with @ConvertGroup annotation. Check this out http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-group-conversion

Igor G.
  • 6,955
  • 6
  • 26
  • 26
  • So with this solution you would now annotate the handler method param with the regular Valid annotation, but you would also annotate it with the ConvertGroup. I guess it could keep you from having to use the Spring validator if you are averse to them. – digitaljoel Aug 07 '13 at 16:06
1

As for validation groups support inside @Valid annotation - there is a way to do it, that I've recently found, it's redefining default group for validated bean:

@GroupSequence({TestForm.class, FirstGroup.class, SecondGroup.class})
class TestForm {

    @NotEmpty
    public String firstField;

    @NotEmpty(groups=FirstGroup.class)
    public String secondField; //not validated when firstField validation fails

    @NotEmpty(groups=SecondGroup.class)
    public String thirdField; //not validated when secondField validation fails
}

Now, you can still use @Valid, yet preserving order with validation groups.

Adam Jurczyk
  • 2,153
  • 12
  • 16
  • Interesting solution. This will work if you want to always do all the validation, but if in some locations you only want to validate SecondGroup and in others you only want FirstGroup this won't help. – digitaljoel Oct 17 '11 at 19:05
  • Yes, it has few pitfalls. But in general, when it comes to more complex validation, with conditional and ordered validators, annotations fails miserable :( – Adam Jurczyk Oct 17 '11 at 21:53