Site icon

Jersey Bean validation of REST request / query parameters using standard annotation (example) – I

Example – Apply validation to RESTful web service.

We will validate the request parameters of RESTFul web service using jersey bean validation. We have already discussed to create RESTful web service using jersey framework. We will use following annotations provided by Jersey & java framework.
@DecimalMin, @Size, @Pattern, @Min etc.

Example of validation in REST resource

 @GET
 @Path("/validate")
 public Response validateStudent(
    @Size(min = 2, max = 25, message = "firstName Length should be between 2 and 25")
    @QueryParam("firstName") String firstName,
    @Size(min = 2, max = 25, message = "lastName Length should be between 2 and 25")
    @QueryParam("lastName") String lastName,

    @Min(value=15, message = "age should not be less that 15")
    @QueryParam("age")
    String age) throws ValidationException {

In “/validate” request (we will show sooner), we are validating “firstName” query param, we are ensuring that it should have at least 2 character and at max it can have 25 character. Besides, we are specifying the error message that will be generated once there is any violation e.g. if firstName have length less that 2 then exception message of “firstName Length should be between 2 and 25 character” will be sent back.

Jersey Maven dependencies (bean validation)

<dependency>
	<groupId>org.glassfish.jersey.containers</groupId>
	<artifactId>jersey-container-servlet</artifactId>
	<version>${jersey_version}</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.media</groupId>
	<artifactId>jersey-media-json-jackson</artifactId>
	<version>${jersey_version}</version>
</dependency>
<dependency>
	<groupId>org.glassfish.jersey.ext</groupId>
	<artifactId>jersey-bean-validation</artifactId>
	<version>${jersey_version}</version>
</dependency>

Program – validation of REST request / query parameters (standard annotations)

1.) StudentResource class:

package org.learn.resource;

import org.learn.model.Student;

import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Date;


@Path("/student")
public class StudentResource {

    private static final String text = "Message from Server :\n%s";

    @GET
    @Consumes(MediaType.TEXT_PLAIN)
    public Response registerStudent() {
        String response = String.format(text, new Date());
        return Response.status(Response.Status.OK).entity(response).type(MediaType.TEXT_PLAIN).build();
    }

    @GET
    @Path("/validate")
    public Response validateStudent(
            @Size(min = 2, max = 25, message = "firstName Length should be between 2 and 25 character")
            @QueryParam("firstName") String firstName,

            @Size(min = 2, max = 25, message = "lastName Length should be between 2 and 25 character")
            @QueryParam("lastName") String lastName,

            @Min(value = 15, message = "age should not be less that 15")
            @QueryParam("age")
                    String age) throws ValidationException {

        String student = String.format("firstName: %s, lastName: %s, age: %s", firstName, lastName, age);
        String response = String.format(text, student);
        return Response.status(Response.Status.OK).entity(response).type(MediaType.TEXT_PLAIN).build();
    }

    @POST
    @Path("/register")
    public Response registerStudent(
            @Valid Student student) throws ValidationException {

        String response = String.format(text, student);
        return Response.status(Response.Status.OK).entity(response).type(MediaType.TEXT_PLAIN).build();
    }
}

Suppose client used API “host:port:/student/valiadte” to post the request to our service. We have deployed our application at root, so do not have any context path in our request url.

The request response for couple of APIs are

  1. Requet API  – /student/validate:
    http://localhost:9090/student/validate?firstName=don&lastName=brad&age=16
    Response from service:
    Message from Server :
    firstName: don, lastName: brad, age: 16
  2. Request API  – /student/register :
    http://localhost:9090/student/register
    request raised from client:
    {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don.bradman@ymail.com”,”age”:”18″}

2.) Student class:

  1. The client raise the JSON request like
    {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don.bradman@ymail.com”,”age”:”18″}
  2. We have defined @DecimalMin annotation which specify the minimum age of student.
  3. In our input we have specified age as 18 which is within the min and max defined on age data member.
  4. Also, we have used @Pattern annotation to validate the email address.
    • This validation will validate the “don.bradman@ymail.com” email of incoming object.
    • If there is any violations in input parameters, then ValidationException will be raised.
  5. We have defined ValidationException mapper class to catch all validation exceptions.
package org.learn.model;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "student")
public class Student {

    @DecimalMin(value = "15", message = "Student shall be minimum of age 15 yr")
    @DecimalMax(value = "30", message = "Student can not have age more than 30 yr")
    private int age;

    @Size(min = 1, max = 25, message = "The length of firstName should be between 1 to 25")
    private String firstName;

    @Size(min = 1, max = 25, message = "The length of firstName should be between 1 to 25")
    private String lastName;

    @Pattern(message = "Invalid Email Address->" +
            "Valid emails:user@gmail.com or my.user@domain.com etc.",
            regexp = "^[a-zA-Z0-9_!#$%&�*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$")
    private String email;


    public String getEmail() {
        return email;
    }

    public int getAge() {
        return age;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Student() {

    }

    public String toString() {
        return String.format("firstName : %s, lastName: %s, email : %s, age: %s",
                firstName, lastName, email, age);
    }
}

3.) ValidationExceptionMapper class:

Examples of Validation Exceptions:

  1. The json used to send to call the api. As we do not have firstName.
    {“firstName”:””,”lastName”:”last”,”email”:”lovetojava@ymail.com”,”age”:”15″}
    Exception occurred:
    registerStudent.arg0.firstName The length of firstName should be between 1 to 25
  2. Invalid Email Address
    {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don bradman@ymail.com”,”age”:”18″}
    Exception occurred :
    registerStudent.arg0.email Invalid Email Address->Valid emails:user@gmail.com or my.user@domain.com etc.Now let us take at cod of ValidationException
package org.learn.exception;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class ValidationExceptionMapper implements ExceptionMapper<javax.validation.ValidationException> {

    @Override
    public Response toResponse(javax.validation.ValidationException e) {
        final StringBuilder strBuilder = new StringBuilder();
        for (ConstraintViolation<?> cv : ((ConstraintViolationException) e).getConstraintViolations()) {
            strBuilder.append(cv.getPropertyPath().toString() + " " + cv.getMessage());
        }
        return Response
                .status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
                .type(MediaType.TEXT_PLAIN)
                .entity(strBuilder.toString())
                .build();
    }
}

4.) ApplicationExceptionMapper class:

package org.learn.exception;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class ApplicationExceptionMapper implements ExceptionMapper<Exception> {

    public Response toResponse(Exception e) {
        return Response
                .status(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())
                .type(MediaType.TEXT_PLAIN)
                .entity(e.getMessage())
                .build();
    }
}

Output –  Jersey bean validation for REST request/query parameters

 

    1. Requests for http://localhost:9090/student/validate
      Request: GET /student/validate
      http://localhost:9090/student/validate?firstName=don&lastName=brad&age=16
      Response:
      Message from Server :
      firstName: don, lastName: brad, age: 16
    2. Request: GET /student/validate
      http://localhost:9090/student/validate?firstName=&lastName=brad&age=16
      Response:
      registerStudent.arg0 firstName Length should be between 2 and 25 character
    3. Request – We have provided the invalid age, so we will get exception message from server
      http://localhost:9090/student/validate?firstName=don&lastName=brad&age=10
      Response:
      registerStudent.arg2 age should not be less that 15
    4. http://localhost:9090/student/register
      Request: POST /student/register
      {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don.bradman@ymail.com”,”age”:”18″}
      Response:
      Message from Server :
      firstName : Don, lastName: bradman, email : don.bradman@ymail.com, age: 18
    5. Request: POST /student/register
      {“firstName”:””,”lastName”:”last”,”email”:”lovetoyogesh@ymail.com”,”age”:”15″}
      Response:
      registerStudent.arg0.firstName The length of firstName should be between 1 to 25
    6. Request: POST /student/register
      {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don bradman@ymail.com”,”age”:”18″}
      Response:
      registerStudent.arg0.email Invalid Email Address->Valid emails:user@gmail.com or
      my.user@domain.com etc.
    7. Request: POST /student/register
      {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don.bradman@ymail.com”,”age”:”14″}
      Response:
      registerStudent.arg0.age Student shall be minimum of age 15 yr
    8. Request: POST /student/register
      {“firstName”:”Don”,”lastName”:”bradman”,”email”:”don.bradman@ymail.com”,”age”:”40″}
      Response:
      registerStudent.arg0.age Student can not have age more than 30 yr

 

Download code – Jersey bean validation RESTFul web service

Exit mobile version