Spring Validation, Thymeleaf and SpEL
In this tutorial, we will learn to implement a small app using the Thymeleaf template engine and make use of the powerful Expression Language which the framework offers us. We will also cover the basics of Bean validation in Spring.
As already mentioned in our previous articles of the series, Spring framework is an open source Java platform that provides MVC infrastructure support for developing robust Java applications very easily and very rapidly using recommended MVC pattern.
Bean Validation
JSR 303 is a specification of the Java API for bean validation, part of JavaEE and JavaSE, which ensures that the characteristics of a Java bean meet specific behaviour, using Java annotations such as @NotNull, @Min, and @Max.
JSR 349 extends JSR 303, also includes dynamic expression evaluation in constraint violation messages, message interpolation, and much more.
Let’s start by integrating the Maven dependencies for validation and the Hibernate validator as well:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>5.2.1.Final</version>
</dependency>
It is worth noticing that hibernate-validator is completely different from the persistence part of Hibernate and by adding it as a dependency, we’re not adding these persistence power in our demo.
Let’s make a bean to describe how the Java annotations work:
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Product {
@NotNull(message = "Product name cannot be null")
private String name;
@AssertTrue
private boolean isAvailable;
@Size(min = 10, max = 200, message = "Description must be between 10 and 200 characters")
private String description;
@Min(value = 0, message = "Stock should not be less than 0")
@Max(value = 150, message = "Stock should not be greater than 100")
private int stock;
// standard setters and getters
}
Let’s learn about each standard JSR annotation used in the example above:
- @NotNull – Validates that the annotated property value is not null
- @AssertTrue – Confirms that the annotated property value is true
- @Size – Validates that the annotated property value has a size between the attributes min and max; can be applied to String, Collection, Map, and array properties
- @Min – Validates that the annotated property has a value no smaller than the value attribute
- @Max – Validates that the annotated property has a value no larger than the value attribute
The message attribute is common to all of the annotations. This is the message that is usually rendered when the value of the respective property fails validation.
Finally, beyond the standard annotations, there are a few specific ones that Hibernate Validator adds on top; these aren’t part of the standard spec, but they do sometimes make validation a lot easier.
Thymeleaf
Thymeleaf is a Java template engine for processing and creating HTML, XML, JavaScript, CSS, and text.
Let’s start by adding relevant maven dependencies,
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
In the Spring config class, we will configure the Thymeleaf template resolver as a bean, as shown:
@Bean
@Description("Thymeleaf Template Resolver")
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
@Bean
@Description("Thymeleaf Template Engine")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setTemplateEngineMessageSource(messageSource());
return templateEngine;
}
Finally, integrate ThymeleafViewResolver as a bean:
@Bean
@Description("Thymeleaf View Resolver")
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setOrder(1);
return viewResolver;
}
View model attribute
The th:text=”${attributename}” tag attribute can be used to show the value of model attribute. Let’s put a model attribute with the name serverTime in the controller class:
model.addAttribute("serverTime", dateFormat.format(new Date()));
The HTML code to display the value of serverTime attribute:
Current time is <span th:text="${serverTime}" />
Conditional evaluation
Let’s consider a User bean with an attribute for gender:
public class User implements Serializable {
private Integer id;
private String name;
private Character gender;
// standard getters and setters
}
To display gender based on the attribute, we can do:
<td>
<span th:if="${student.gender} == 'M'" th:text="Male" />
<span th:unless="${student.gender} == 'M'" th:text="Female" />
</td>
Display collection attributes
If the model attribute is a collection of objects, the th:each tag attribute can be used to iterate over it. Let’s define a Student bean class with two fields, id and name:
public class Student implements Serializable {
private Integer id;
private String name;
// standard getters and setters
}
Now we will add a list of students as model attribute in the controller class:
List<Student> students = new ArrayList<Student>();
// logic to build student data
model.addAttribute("students", students);
Now, let’s use Thymeleaf template code to go over the list of students and display all field values:
<tbody>
<tr th:each="student: ${students}">
<td th:text="${student.id}" />
<td th:text="${student.name}" />
</tr>
</tbody>
SpEL
The Spring Expression Language, or SpEL for short, is a useful and powerful expression language that supports querying and manipulating an object graph at runtime. It can be used with XML or annotation-based Spring configurations.
There are several operators available in the language:
Type |
Operators |
Arithmetic |
+, -, *, /, %, ^, div, mod |
Relational |
<, >, ==, !=, <=, >=, lt, gt, eq, ne, le, ge |
Logical |
and, or, not, &&, ||, ! |
Conditional |
?: |
Regex |
matches |
SpEL expressions start with the # symbol, and are surrounded by braces: #{expression}. Properties can be referenced in a similar way, starting with a $ symbol, and surrounded in braces: ${property.name}. Property placeholders cannot contain SpEL expressions, but expressions can contain property references:
#{${someProperty} + 2}
In the preceding example, if someProperty has a value of 2, than the resulting expression would be 2 + 2, which would be evaluated to 4.
Referencing a Bean
Let’s define a bean and then use it with HTML and SpEL to show its property values:
public class Engine {
private int capacity;
private int horsePower;
private int numberOfCylinders;
// Getters and setters
}
public class Car {
private String make;
private int model;
private Engine engine;
private int horsePower;
// Getters and setters
}
In HTML using SpEL,
<bean id="engine" class="com.discoversdk.spel.Engine">
<property name="capacity" value="3200"/>
<property name="horsePower" value="250"/>
<property name="numberOfCylinders" value="6"/>
</bean>
<bean id="someCar" class="com.discoversdk.spel.Car">
<property name="make" value="Some make"/>
<property name="model" value="Some model"/>
<property name="engine" value="#{engine}"/>
<property name="horsePower" value="#{engine.horsePower}"/>
</bean>
Take a look at the someCar bean. The engine and horsePower fields of someCar use expressions that are bean references to the engine bean and horsePower field respectively.
To do the same with annotation-based configurations, use the @Value(“#{expression}”) annotation.
Conclusion
SpEL is a powerful, well-supported expression language that can be used across all the products in the Spring portfolio. It can be used to configure Spring applications or to write parsers to perform more general tasks in any application.
Apart from covering SpEL, we went through Java Bean validations and Thymeleaf templating engine.
Visit the homepage to compare the best Java SDKs.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment