Domanda

I've got a simple class which get's validated using the boolean isValid() method, which works and of course the error message is at class/type level.

Here's my simple class:

public class NewPasswordDTO {
    @NotNull
    public String password;

    @NotNull
    public String confirmation;

    @AssertTrue(message="Passwords must match.")
    protected boolean isValid() {
        return password.equals(confirmation);
    }
}

But what I really want is something like that:

public class NewPasswordDTO {
    @NotNull
    @Equals("confirmation", message="...")
    public String password;

    @NotNull
    public String confirmation;
}

So the error message would be set at field level and not at class/type level.

Is this possible somehow? Maybe using a custom Validator for that class?

Thanks in advance!

SOLUTION:

Thanks to Gunnar! I've just came up with a nice, universal solution :-). I simply used (means copy & paste) the code from Hibernates @ScriptAssert and ScriptAssertValidator and modified it slightly:

@ScriptAssert:

  • Add new String field(). (this is where the error message gets appended)

ScriptAssertValidator:

  • Inside the initialize method, make sure to also save the fieldName and message properties, because we need to access them in the next step

  • Add this snippet at the bottom of isValid method:

    context.buildConstraintViolationWithTemplate(errorMessage) .addPropertyNode(fieldName).addConstraintViolation();

  • Also add context.disableDefaultConstraintViolation(); somewhere inside the isValid method to not generate the default error message which else would get appended at class level.

And that's it. Now I can use it like that:

@FieldScriptAssert(lang="javascript", script="_this.password.equals(_this.confirmation)", field="password", message="...")
public class NewPasswordDTO { ... }
È stato utile?

Soluzione 2

Simple answer : It is not (unless you implement it) :http://docs.oracle.com/javaee/6/api/javax/validation/constraints/package-summary.html shows all annotation constraints. Of course you could inject your string as a resource in your class by @producer and so on (which recently is discussed to be removed in jdk8), but you could not use this value for your assert.
In reply to the comment:
This was asuming that the nature is a constant string which you would like to use as a string resource.And then of course it is possible to write your own class based on java.lang.string with a @Producer which is then @Inject - able. Though it is certainly not the way I personally would deal with constant strings.

Altri suggerimenti

You either could use the @ScriptAssert constraint on the class (note that a constraint should always be side-effect free, so it's not a good idea to alter the state of the validated bean; instead you should just check whether the two fieldss match) or you implement a custom class-level constraint.

The latter also allows to point to a custom property path for the constraint violation, which it allows to mark the "confirmation" property as erroneous instead of the complete class.

If you’re using the Spring Framework, then as an alternative to the @ScriptAssert using a JSR 223 scripting, you can use the @SpELAssert that uses the Spring Expression Language (SpEL). The advantage is that it doesn’t need any JSR 223 compliant scripting engine which may not be available on some environments. See this answer for more information.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top