How can I customize the Validator for Hibernate Validator's method validation with Seam? - seam

I'm using Hibernate Validator and added some custom validation annotations, resource bundle location and a custom message interpolator. This is all done by customizing the Validator at bootstrapping time.
Now I'm trying to validate methods, but of course I don't get my nicely configured Validator, since the standard Validator is injected for #AutoValidating.
How can I customize the Validator within Seam Validation?
Here's how I create the Validator:
public static javax.validation.Validator getBeanValidator(final Locale locale,
final ResourceBundle... resourceBundles) {
HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class).configure();
FallbackResourceBundleLocator resourceBundleLocator = new FallbackResourceBundleLocator(
configuration.getDefaultResourceBundleLocator(), resourceBundles);
configuration.messageInterpolator(new FieldMessageInterpolator(locale, resourceBundleLocator));
javax.validation.ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
return validatorFactory.getValidator();
}

You could try to configure the default validator using META-INF/validation.xml, which is the validator used by Seam Validation.
Alternatively you could create your own interceptor based on the one from Seam Validation, and use your custom configured Validator there.

Related

Spring MVC 5.*: Wizard Forms validation with Validator

I am creating a multipage forms application. I'd like to use Validator interface to validate the content provided by the user.
The question: Is this https://mkyong.com/spring-mvc/spring-mvc-handling-multipage-forms-with-abstractwizardformcontroller/ approach still valid in terms of Spring MVC 5.2.*?
Ofc, we should forget about AbstractWizardFormController for a moment.
And answering on my own question:
You do not have to do it. Normally validator will catch errors before the page was switched. Basically, one needs to implement validator as told here https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/core.html#validator. Then bind it to the controller with
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(<validaotrs_variable_name>);
}
And then use #Validated on #ModelAttribute("myobjectnameintemplate") MyPojo myPojo.
That is it.
If the one wants to validate page at a time, then I think it is necessary to run validation methods separately. For this I found a number of answers on stackoverflow:
One can use #Valid and validation groups (Hibernate)
Simple switch case in validate() based on the current page or something else
Nested objects in one object that is being populated, and multiple validators as described here https://docs.spring.io/spring/docs/5.2.6.RELEASE/spring-framework-reference/core.html#validator

How do I override fluentvalidator extension methods?

I am using .NET ASP.NET MVC 4. For validation I am using Fluent validation. I am new to this. How can I override a method of the DefaultValidatorExtensions class?
I found one solution.
Create basevalidator class which inherited both IValidatorInterceptor and AbstractValidator. But I am not getting how to override validation methods.
Actually I want to change the default message of any validation method. The message is common for all attributes for some validations, so I want to override those validation methods rather to use 'WithMessage()'.
For example:
RuleFor(x => x.Name).NotEmpty(); will return " 'Name' should not be empty." But I want message 'Required'.
I found an answer on this link. I think it can help you:
https://fluentvalidation.net/localization#default-messages
If you want to replace all (or some) of FluentValidation’s default messages then you can do this by implementing a custom version of the ILanguageManager interface.
For example, the default message for the NotNull validator is '{PropertyName}' must not be empty. If you wanted to replace this message for all uses of the NotNull validator in your application, you could write a custom Language Manager:
public class CustomLanguageManager : FluentValidation.Resources.LanguageManager {
public CustomLanguageManager() {
AddTranslation("en", "NotNullValidator", "'{PropertyName}' is required.");
}
}
Here we have a custom class that inherits from the base LanguageManager. In its constructor we call the AddTranslation method passing in the language we’re using, the name of the validator we want to override, and the new message.
Once this is done, we can replace the default LanguageManager by setting the LanaguageManager property in the static ValidatorOptions class during your application’s startup routine:
ValidatorOptions.LanguageManager = new CustomLanguageManager();
This is a simple example that only replaces one validator’s message in English only, but could be extended to replace the messages for all languages. Instead of inheriting from the default LanguageManager, you could also implement the ILanguageManager interface directly if you want to load the messages from a completely different location other than the FluentValidation default (for example, if you wanted to store FluentValidation’s default messages in a database).
Of course, if all you want to do is replace this message for a single use of a validator, then you could just use WithMessage("'{PropertyName}' is required");

ASP.Net Core and model validation

Suppose I have a model which I need to validate. I can add some validate attributes to the properties I want to validate. And it works pretty fine. But at some point I want to validate this model depending on other models (I will need t query db). And here there are some options.
create a special validate attribute which will lack dependency injection
delegate this validation to some business layer (manager) and in controller
_
if (Model.IsValid) {
if(!await Manager.Create(myModel)) {
Model.CopyErrors(Manager.Errors); // Extension method for Model
}
}
So what is the correct way of handling such a situation?
P.S. I am using asp.net core and entity framework core
What you need is Fluent Validation

Check that each element in collection is not empty

How to simply check that each element in collection of strings is not empty using some annotation?
List<String> strings;
There is no simple way to achieve this with Bean Validation / Hibernate Validator.
You are dealing with the same issue discussed in the Validator HV-296 as well the Bean Validation BVAL-202 issue tracker.
One thing you could try is to implement a
public class NotEmptyValidator implements ConstraintValidator<NotEmpty, Iterable<String>>
You then register this custom constraint validator via validation.xml. However, this is more than just adding an annotation.
Hibernate Validator 5.2 will offer support for Java 8 type annotations. There you will be able to write:
List<#NotEmpty String> strings;
See also HV-877.

adding constraints dynamically to hibernate validator in a spring mvc application

I am using hibernate validator in my spring mvc app. With the following simple steps I am able to get the validation happen.
pom.xml changes to add hibernate validator.
Annotated the beans with some constraints.
Annotated the controller method parameter with #Valid.
Handled the MethodArgumentNotValidException
I don't want to add the constraints to the beans, instead want to add them to the beans dynamically. This dynamic addition need to happen during application startup and just once.
In the hibernate validator documentation, I see the following snippet.
constraintMapping.type( Car.class ).property( "manufacturer", FIELD ).constraint( new NotNullDef() )
My question is, how do I get a handle to this ConstraintMapping instance ? I see that Spring instantiates the hibernate validator through the LocalValidatorFactoryBean.
thanks for your help.
You get it from the HibernateValidatorConfiguration - http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html_single/#section-programmatic-api
HibernateValidatorConfiguration configuration = Validation
        .byProvider( HibernateValidator.class )
        .configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
    .type( Car.class )
        .property( "manufacturer", FIELD )
            .constraint( new NotNullDef() )
        .property( "licensePlate", FIELD )
            .ignoreAnnotations()
            .constraint( new NotNullDef() )
            .constraint( new SizeDef().min( 2 ).max( 14 ) )
    .type( RentalCar.class )
        .property( "rentalStation", METHOD )
            .constraint( new NotNullDef() );
Validator validator = configuration.addMapping( constraintMapping )
        .buildValidatorFactory()
        .getValidator();
This mean, however, that you probably cannot use LocalValidatorFactoryBean, but you probably can just write your own.  

Resources