Book Image

Java EE 8 and Angular

By : Prashant Padmanabhan
Book Image

Java EE 8 and Angular

By: Prashant Padmanabhan

Overview of this book

The demand for modern and high performing web enterprise applications is growing rapidly. No more is a basic HTML frontend enough to meet customer demands. This book will be your one-stop guide to build outstanding enterprise web applications with Java EE and Angular. It will teach you how to harness the power of Java EE to build sturdy backends while applying Angular on the frontend. Your journey to building modern web enterprise applications starts here! The book starts with a brief introduction to the fundamentals of Java EE and all the new APIs offered in the latest release. Armed with the knowledge of Java EE 8, you will go over what it's like to build an end-to-end application, configure database connection for JPA, and build scalable microservices using RESTful APIs running in Docker containers. Taking advantage of the Payara Micro capabilities, you will build an Issue Management System, which will have various features exposed as services using the Java EE backend. With a detailed coverage of Angular fundamentals, the book will expand the Issue Management System by building a modern single page application frontend. Moving forward, you will learn to fit both the pieces together, that is, the frontend Angular application with the backend Java EE microservices. As each unit in a microservice promotes high cohesion, you will learn different ways in which independent units can be tested efficiently. Finishing off with concepts on securing your enterprise applications, this book is a handson guide for building modern web applications.
Table of Contents (16 chapters)

Bean Validation 2.0

With the advent of so many technical choices such as microservices, rich front end applications, data stores like NoSQL, and a plethora of systems always communicating with each other and exchanging data, it's vital to get the data validation done right. There's a growing need for data validation services; most APIs typically have some input and output as part of their contract. The input and output are usually the candidates for applying some validation on.

Imagine you are trying to register a user in the system but the client didn't send the username or email which was required by your business logic. You would want to validate the input against the constraints defined by your application. In an HTML-based client, if you were building a HTML form, you would want the input to meet certain criteria before passing it down for further processing. These validations might be handled in the client-side and/or in your server-side processing. Validation is such a common requirement for any API that there’s room for standardizing these constraints and applying them in an intuitive way on your APIs. Bean Validation specification defines a set of built-in validations that can be used on your APIs in a declarative way using annotations. It would be naive to think this covers every possible case, thus there’s a way to use your own custom validators when the built-in ones just won't do.

As you might have guessed, this kind of validation is not only restricted to JAXRS web services but can be applied across various specs such as JSF, JPA, CDI and even third-party frameworks such as Spring, Vaadin, and many more. Bean Validation allows for writing expressive APIs with constraints defined in a declarative manner, which get validated on invocation.

Now, if you are familiar with the earlier version, then you might be wondering what's changed in 2.0. Well, the main driving factor for the 2.0 release involved leveraging the language changes brought in by Java 8 for the purpose of validation. We have new types, such as LocalTime or LocalDate, as well as the possibility to repeat annotations or use lambda expressions. So, an update to support and leverage these changes was only logical.

Let's assume we have a REST resource (web service) that takes a team as input to be added into the system and outputs the updated list of teams. Here, we want a name to be provided for a team and this can’t be null. So, here's the code for doing just that:

public class Team {     
private Long id;
//NotNull suggest the name of a team can’t be null
@NotNull
private String name;
//Rest of the code can be ignored
...
}

@Path("teams")
public class TeamResource {
/* A method to add new team, which requires the input
of Team to be Valid
*/
@POST
@Produces(MediaType.APPLICATION_JSON)
public List add(@Valid Team team) {
//Rest of the code can be ignored
...
}
}

Let's assume we have the preceding JAXRS resource running on a server. If you invoke this API and supply team data as input, then it must have a name in order for the input to pass the validation constraint. In other words, valid team input has the name field satisfying the NotNull constraint. Similarly, it's possible to put a constraint on the result as well. A rewritten method signature is shown as follows, which puts a NotNull constraint on the response:

@POST
@Produces(MediaType.APPLICATION_JSON)
public @NotNull List<Team> add(@Valid Team team) { ... }

With Bean Validation 2.0, a whole new set of possibilities have been added. One of the biggest features is validating collections. It's now possible to validate the contents of a type-safe collection. We could, for instance, add type annotations to validate the contents of generic collections such as List<@NotNull Team>, or even better, List<@NotNull @Valid Team>:

@POST
@Produces(MediaType.APPLICATION_JSON)
public @NotNull List<@NotNull @Valid Team> add(@Valid Team team)
{ ... }

You could also use the @Email annotation on a collection like this, List<@Email String>, to ensure the emails present within the list are conforming to the email validation constraint. The API also allows you to supply your own regex to validate the input. Also, it's interesting to note that @Email validation doesn't mean the value cannot be null. What it means is that if a string is present, then it must be a valid email but can be null, too. It's best to separate concerns from the core validation of the email and the NotNull validation for the input.

A few more examples are:

  • List<@Positive Integer> positiveNumbers;
  • Map<@Valid Team, @Positive Integer> teamSizeMap;

In the preceding example, we want our map to have valid team instances as the key, and the value must be a positive integer:

@Size(max=10) 
private List<String> only10itemsWillBeAllowed;

In the preceding case, we want to have a list containing a maximum of 10 items.

A more complex case would be validating a player list with a maximum of 11, and each player must be a valid instance. Valid would mean meeting all validation constraints put on a player class:

@Size(max=11) 
private List<@Valid Player> players;

The preceding constraints provide for a very natural way to put constraints declaratively on your code, which is much more readable and closer to the definition where it’s used.

Another way of validating a collection of items is to put the validation constraint near the type parameter. So, while both the following approaches would work, the latter is preferred:

@Valid
private List<Player> players;

It can also be:

private List<@Valid Player> players; //Preferred

Now, Bean Validation also makes use of the Optional class, where you can put validation on the type it holds. For example:

public Optional<@Valid Team> getTeam() { ... }

A few more built-in constraints worth checking out are @NotBlank, @Future, @Past, @Negative, @Pattern, @Min, and @Max. By default, the Bean Validation API has very nice integration with key life cycle events of other specifications. This allows for all of the validation to happen at key stages of an object's life cycle, such as that of JPA or JSF managed beans.