Skip to main content

Jakarta Validation

Open in ChatGPT

Java Bean Validation is widely recognized as the standard for integrating validation logic into Java applications. It uses a uniform approach to validation by allowing developers to annotate domain model properties with declarative validation constraints. These constraints are enforced at runtime, with options for both built-in and custom-defined rules.

webforJ integrates with Bean Validation through the JakartaValidator adapter, providing full support out of the box.

Installation

It's necessary to include a compatible implementation, such as Hibernate Validator, in your classpath. If your environment doesn't come with this implementation by default, you can add it manually by using the following Maven dependencies:

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.expressly</groupId>
<artifactId>expressly</artifactId>
<version>5.0.0</version>
</dependency>

The JakartaValidator

The JakartaValidator class serves as an adapter, bridging the webforJ binding context with Jakarta Validation. This integration enables the use of complex validation rules directly via annotations in the bean class.

Activating JakartaValidator

To activate the JakartaValidator across the entire context, you typically use the useJakartaValidator parameter when constructing the BindingContext.

BindingContext<User> context = new BindingContext<>(User.class, true);

Defining constraints for bean properties

Annotation-based constraints are directly applied within the bean class to specify validation conditions, as illustrated in the example below:

public class Hero {
@NotEmpty(message = "Name cannot be empty")
@Length(min = 3, max = 20)
private String name;

@NotEmpty(message = "Unspecified power")
@Pattern(regexp = "Fly|Invisible|LaserVision|Speed|Teleportation", message = "Invalid power")
private String power;

// getters and setters
}

Such constraints are as effective as those set programmatically during the binding initialization and produce consistent validation outcomes.

warning

Currently, the JakartaValidator only recognizes constraints that are directly assigned to properties and ignores any validations not directly associated with properties.

Locale-aware validation messages 25.12

Jakarta Validation supports localized constraint messages through standard message interpolation. When you change the app locale, the JakartaValidator needs to know the new locale so it can resolve messages in the correct language.

JakartaValidator implements the LocaleAware interface, which means BindingContext.setLocale() automatically propagates the locale to all Jakarta validators in the context. You don't need to update each validator manually.

BindingContext<Hero> context = new BindingContext<>(Hero.class, true);

// When the locale changes, Jakarta validators automatically
// produce messages in the new locale
context.setLocale(Locale.GERMAN);

In a component that implements LocaleObserver, call context.setLocale() inside onLocaleChange() to keep validation messages in sync with the UI language:

@Override
public void onLocaleChange(LocaleEvent event) {
context.setLocale(event.getLocale());
}

See dynamic validation messages for more on locale-aware validators.