You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Intro

The Intro page provides an overview and describes the motivation for the features described below. This page explains the most important APIs and mechanisms of the property validation module provided by ExtVal. Please note that this page doesn't show all possibilities. If you have any question, please contact the community!

Dependencies

The page ExtVal Modules provides an overview about ExtVal modules and how to add them to your project.

For using the features described in this page, you have to add the core and the property validation module for the JSF version you are using.

Hello-World example

Setup

Required steps for using ExtVal:

  • Download the required ExtVal jar-files or checkout the Source Code and build it. (details)
  • Add these jar-files to your classpath (manually or via maven)
  • Use the annotations (details)

That's it!

The sample page

The sample bean

The result

Available annotations

Simple validation

Annotation

Description

DoubleRange

delegates to the implementation of javax.faces.validator.DoubleRangeValidator

JoinValidation

to reuse (point to) annotations of a different property (see re-use existing annotations)

Length

delegates to the implementation of javax.faces.validator.LengthValidator

LongRange

delegates to the implementation of javax.faces.validator.LongRangeValidator

Pattern

use a regular expression for validation

Required

alternative to the required attribute

SkipValidation

allows to keep validation optional. (the annotations which are afterwards and support this mechanism)

Validator

generic validator to delegate validation to an existing jsf validator e.g.: @Validator(EmailValidator.class)

JPA based validation

JPA annotations are used automatically for UI validation as soon as you:

  • Add myfaces-extval-core-.jar and myfaces-extval-property-validation-.jar to the classpath
  • Use JPA annotations within the model (e.g.: @Column(nullable = false) -> the field is required)

That's it!

(A simple demo is available here: demo_000)

Cross-Validation

Annotation

Description

DateIs

validates if a date is equal, before or after a second date

Equals

validates if two values are equal

NotEquals

validates if two values are different

RequiredIf

validates if a value is required depending on a second value (if it is empty or not)

Existing/3rd party constraints

ExtVal has no special requirements for annotations. It's the responsibility of the validation strategy to know how to validate the annotation.
So you can use annotations within any layer without introducing an ExtVal dependency below the view layer.
If you would like to validate 3rd party annotations you can provide a mapping. With the same mechanism you can replace existing (ExtVal) validation strategies. Find detailed information below.

Custom annotations

ExtVal provides the possibility to validate annotations with so called validation strategies.

The simplest case is to create a custom annotation and to use a name convention for the validator (= validation strategy).
The validation strategy has to implement the ValidationStrategy interface. Or you can extend a class which implements this interface in-/directly. (A simple demo is available here: demo_002, demo_006)

Hint

If you don't like the default conventions, you can provide a custom name mapper, or you provide a mapping between annotations and the validation strategies (via properties file or ExtVal Java API), or ...

Minimal implementation
//my.custom.package.CustomConstraint

@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface CustomConstraint
{
}

//my.custom.package.CustomConstraintValidationStrategy
public class CustomConstraintValidationStrategy implements ValidationStrategy
{
    void validate(FacesContext facesContext, UIComponent uiComponent,
                  MetaDataEntry metaDataEntry, Object convertedObject)
    {
        //custom validation logic
    }
}

That's just the simplest case. You can also use one of the other available name conventions or you can provide a custom convention or a custom name mapper or ...

Hint

It's recommended to use AbstractValidatorAdapter or AbstractAnnotationValidationStrategy instead of ValidationStrategy.

In ExtVal r3+ validation strategies don't have to be aware of empty/null values. So it's safe to delegate to legacy JSF validators.
If a validation strategy should validate such values, it's possible to annotate the validation strategy with @NullValueAwareValidationStrategy and/or @EmptyValueAwareValidationStrategy.

Provide/replace validation strategy mappings

If you don't like to use the name mapping concept, you can provide static mappings between annotations and validation strategies.
Use the convention for a mapping file ( org.apache.myfaces.extensions.validator.custom.strategy_mappings.properties ) (it's customizable)

or use the ExtVal Java API:

Register a resource-bundle file which contains an annotation/validation strategy mapping:

Alternative config approach via a property file
StaticConfiguration<String, String> staticConfig = new StaticResourceBundleConfiguration();
staticConfig.setSourceOfMapping("[custom package + name of the properties file.]");
ExtValContext.getContext().addStaticConfiguration(StaticConfigurationNames.META_DATA_TO_VALIDATION_STRATEGY_CONFIG, staticConfig);

It's also used internally to provide the JPA based validation support. So you can find an example at the PropertyValidationModuleStartupListener.
A similar approach is used internally by the annotation based config extension

This approach is more typesafe - a simple example:

Alternative config approach which manual mapping
StaticInMemoryConfiguration staticConfig = new StaticInMemoryConfiguration();
staticConfig.addMapping(CustomConstraint.class.getName(), CustomValidator.class.getName());
ExtValContext.getContext().addStaticConfiguration(StaticConfigurationNames.META_DATA_TO_VALIDATION_STRATEGY_CONFIG, staticConfig);

Hint

If you also don't like the approach above, you can implement your own ValidationStrategyFactory to introduce your own concept.

I18N support

see Internationalization

Spring support

It's possible to provide a validation strategy as Spring bean.

Use-cases:

  • Inject a Spring bean into the validation strategy
  • AOP exception handling
  • ...
Spring based dependency injection support for validation strategies
<!-- The name of annotation: @CustomRequired -->

<!-- Part of the Spring configuration: -->

<bean id="customRequiredValidationStrategy" class="..." lazy-init="true">
    <property name="messageResolver" ref="customMsgResolver"/>
    <property name="requiredValidationService" ref="demoRequiredValidationService"/>
</bean>

<bean id="customMsgResolver" 
      class="org.apache.myfaces.extensions.validator.core.validation.message.resolver.DefaultValidationErrorMessageResolver"
      lazy-init="true">

    <!-- With JSF 1.2 you can use the var name of resource-bundle see faces-config.xml -->
    <property name="messageBundleVarName" value="messages"/>
</bean>

<bean id="demoRequiredValidationService" class="..."/>

The bean name follows the available name conventions.
(Also custom name conventions are supported.)

A simple demo is available here: demo_106

Furthermore, it's possible to provide a Meta-Data Transformer as Spring bean.

  • No labels