Skip to content

Instantly share code, notes, and snippets.

@gunnarmorling
Last active December 19, 2015 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gunnarmorling/5926975 to your computer and use it in GitHub Desktop.
Save gunnarmorling/5926975 to your computer and use it in GitHub Desktop.

Bean Validation 1.1 Feature Spotlight - Expression Language

It has been a couple of weeks since Bean Validation 1.1 has gone final. In the mean time, the Java EE 7 platform spec has been finalized as well, so it's about time to have a closer look at what you can expect from these updates in relation to Bean Validation and its reference implementation, Hibernate Validator 5.

Over the following weeks, we'll dive into the most exciting new features in a series of blog posts, starting today with the usage of expression language in error messages.

Executive summary

Many users relate the Unified Expression Language (EL) only to the UI technologies JSF and JSP. But it doesn't stop there. Actually, EL has matured over time into an independent language with it's own specification. It can be used in any application layer, in Java EE as well as Java SE based applications.

Bean Validation 1.1 makes use of EL to support the creation of constraint violation messages in a dynamic manner.

Using EL expressions in constraint messages

As an example, let's take a look at the built-in DecimalMax constraint. As of Bean Validation 1.1, this constraint has a new flag named inclusive which specifies whether the given maximum value is inclusive or not. Depending on the flag's value, the constraint's error message should either be "must be less than {value}" or "must be less than or equal to {value}".

This kind of behavior was not easily achievable in Bean Validation 1.0 but it is straight-forward using an EL expression which conditionally adds the "or equal to" part:

"must be less than ${inclusive == true ? 'or equal to ' : ''}{value}"

EL expressions are given in the form ${expression}. You can use them to implement conditional logic as in the example, perform calculations, nicely format values etc. EL 3.0 even has support for lambda expressions. Refer to the EL specification for the complete syntax.

As the {value} expression from the example shows, the Bean Validation 1.0 syntax for referencing attributes is still supported and takes precedence over expression evaluation. So for instance the message "${amount}" would be interpolated into something like "$50".

Referring to the validated value

Besides all attributes of the validated constraint (such as inclusive) you can access the value to which the constraint is applied using the name validatedValue as shown in the following example:

@ValidCustomer( message = "Not a valid customer: ${validatedValue.getName()}" )
public class Customer {

    //...

    public String getName() {
        return name;
    }
}

Here, a violation of the @ValidCustomer constraint would produce a message such as "Not a valid customer: Bob".

Doing some formatting

Finally, a helper for formatting strings is exposed under the name formatter, providing a var-args method format(String format, Object... args) which exactly behaves like java.util.Formatter.format(String format, Object... args). This comes in handy if you e.g. want to format number values in a special way:

public class Order {

    @DecimalMin(value="20.00", message="Order value too low: € ${formatter.format('%08.2f', validatedValue)}")
    private final BigDecimal value;

    //...
}

The shown format expression causes the value to be padded with leading zeros, so if the @DecimalMin constraint is violated, you would get a message such as "Order value too low: € 00017.89".

EL and the classpath

In order to use the expression language feature, you need an UEL implementation on your classpath. That's usually the case when running in a Java EE container such as WildFly but you'll have to add an implementation by yourself if your application runs in a plain Java SE environment. Two implementations known to work with Hibernate Validator are the UEL reference implementation and JUEL.

Finally a special tip to all the Tomcat users out there. Hibernate Validator requires at least EL 2.2. This is part of Tomcat 7, so you should experience no problems there. Tomcat 6 only comes with an EL 2.1 implementation, though. So does this mean you can't experience all the Bean Validation 1.1 goodness on Tomcat 6 then? Luckily not, it just requires a little preparation. Check out the Hibernate Validator FAQ to learn how to update the Tomcat EL libraries.

Trying it out yourself

If you'd like to give the expression language feature a spin, just grab the latest Hibernate Validator release from here or pull it into your project using its GAV coordinates org.hibernate.hibernate-validator.5.0.1.Final. If you feel adventurous and like playing with the latest bits, you also may build WildFly yourself from its sources. It has been updated to Hibernate Validator 5 a couple of days ago.

The recently revamped reference guide has all the information you need, and we're happy to help you with any questions in the forum.

@hferentschik
Copy link

so it's about time to have a closer look at what you can expect from this update to the Bean Validation spec and its reference implementation, Hibernate Validator 5

so it's about time to have a closer look at what you can expect from this update in relation to Bean Validation and its reference implementation, Hibernate Validator 5

@hferentschik
Copy link

One of the lesser known facts about Java EE is that the

Did you know ....

(trying to make it more personal and less formal!? just an idea)

@hferentschik
Copy link

This kind of behavior was not easily achievable in Bean Validation 1.0

not easily or just not?

@hferentschik
Copy link

and much more.

or format the validated value

(and much more feels vague)

@hferentschik
Copy link

As shown in the example, the Bean Validation 1.0 syntax for attribute references ({attribute}) is still supported and takes precedence over expression evaluation.

Where exactly do I see that in the example? I guess you refer to {value}. You should make this explicit

@hferentschik
Copy link

running on a Java EE container

on or in (not sure!?)

I think I prefer running in a container

@hferentschik
Copy link

make Wildfly a link?

@emmanuelbernard
Copy link

I did fix a few minor things, check out this fork https://gist.github.com/emmanuelbernard/5927643/revisions

Otherwise I would personally use a shorter, lighter and less formal tone but yours is not out of place and that's yours.

I would however add a summary section for people in a hurry at the beginning of the blog post. I would also add some structure with h3 titles to mark the progression and make the reading easier.

Also I would mention Tomcat and how to work around potential issues.

Executive summary

blah blah

key example

blah b;ah

Let's dive in EL based error messages

blah

Using EL expressions

...

attribute injection

...

injecting the validated value

....

doing some formatting

...

Using all of this

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment