6 minutes
From Spring Boot To Jakarta EE 11: How Payara Starter Eases The Transition
If you’ve been living in the Spring ecosystem, you’re used to fast project setup. Spring Initializr gives you a […]
Welcome to this week’s Friday Nugget and congratulations, you’ve made it through the week! What better way to kick off the weekend than by talking about simplifying something that is essential to ensure that data flows smoothly between clients and servers, meeting all necessary formats, types and rules. Correct, we are talking about validation.
Validation is an important aspect of all applications, especially web services consumed by a myriad of clients. When handling incoming requests and outgoing responses, there’s the need to guarantee that the data conform to expected formats, types or business rules. Validation in Jakarta REST (JAX-RS) web services is critical not just for the above mentioned reasons, but also to ensure consistency for both clients and the server. However, rolling out custom validation from scratch can be expensive and time consuming. That’s definitely a task no one wants to tackle on a Friday. Is there a better way? Of course there is – with Jakarta Bean Validation. Let’s dig in.
Jakarta RESTful Web Services (JAX-RS) integrates with the Jakarta Bean Validation API, providing a straightforward approach to validating both incoming and outgoing entities. This integration not only simplifies the code but also brings the power of constraint annotations directly into your RESTful service layers. You get to use Jakarta EE’s famed annotation driven paradigm to implement validation constraints right in the web layer of your application.
In Jakarta RESTful Web Services, validation can occur at multiple places:
When a client sends a request to a JAX-RS service, the request’s payload (e.g., JSON, XML) might need validation. Using Jakarta Bean Validation annotations, you can enforce constraints directly on the request body. Let’s take an example of a User entity:
public class User {
@NotNull
private String username;
@Email
private String email;
@Size(min = 6, max = 20)
private String password;
// Obligatory Getters and setters...
}
Here, the User fields must meet specific criteria, such as being non-null, properly formatted as an email, and within a size range for the password.
Within a JAX-RS resource method, you can validate the User object like this:
@POST
@Path("/register")
@Consumes(MediaType.APPLICATION_JSON)
public Response registerUser(@Valid User user) {
// Some fancy user processing through some CDI controller…
return Response.ok().build();
}
The @Valid annotation tells the runtime that it should validate the User object according to the annotated constraints. If validation fails, a ConstraintViolationException is thrown, which can be automatically converted to beautiful error messages that get sent to the client. This is an example of validating whole classes.
You can also validate individual method parameters by directly annotating them with any of the Jakarta Bean Validation constraints as follows.
@GET
@Path("/register")
@Consumes(MediaType.APPLICATION_JSON)
public User loadUser(@QueryParam(“email”) @Email String userEmail) {
// Fetch and return the user via their email
return userController.getUserByEmail(userEmail);
}
In the above example, the loadUser method directly constrains the “email” query param with @Email. This will cause the runtime to ensure the passed query param has a valid email format, such as a@b.com. A violation will cause the same ConstraintViolationException to be thrown, which again, you can customize.
Validating your Jakarta REST resources comes with a number of benefits including:
The default validation constraints (@NotNull, @Size, @Email, etc.) are useful, but real-world applications often require custom validation rules tailored to specific business needs. Jakarta Bean Validation allows you to define custom constraints, which you can then use within your JAX-RS resources, much like any other built-in annotation.
Example of a custom constraint:
@Documented
@Constraint(validatedBy = StrongPasswordValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface StrongPassword {
String message() default "Weak password";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
And the associated validator:
public class StrongPasswordValidator implements ConstraintValidator<StrongPassword, String> {
@Override
public boolean isValid(String password, ConstraintValidatorContext context) {
// Implement your custom validation logic here
return password != null && password.length() > 8 && password.matches("[a-zA-Z0-9]*");
}
}
You can now use the @StrongPassword constraint annotation anywhere any of the built-in constraint annotations can be used.
While validation is powerful, keep in mind:
Validation in Jakarta RESTful Web (JAX-RS) Services offers a structured way to enforce rules and consistency across APIs. With built-in support for Jakarta Bean Validation, creating reliable, error-resistant RESTful web services has never been easier. Whether you’re validating simple field constraints or implementing complex custom rules, the integration makes it straightforward and flexible. So, next time you need to implement validation in your Jakarta REST resources, remember Jakarta Bean Validation is baked into the JAX-RS for your coding pleasure! Download your free trial of Payara Server Enterprise today and start creating that web app you always dreamed of!
That’s it for this week’s Nugget Friday! Happy Coding!
Share:
6 minutes
If you’ve been living in the Spring ecosystem, you’re used to fast project setup. Spring Initializr gives you a […]
3 minutes
Exploring the Future of AI with the Jakarta EE Community At Payara, we’re passionate about pushing the boundaries of […]
5 minutes
Legacy Java applications built on enterprise standards don’t have to be roadblocks to modernization. When applications follow established specifications […]
is this supported on payara 4?
Is it possible to configure fast fail or first fail