Spring Request Body Validation For List

Posted By : Bobby Sharma | 23-Sep-2018

In Spring MVC the @RequestBody annotation indicates a method parameter should be bound to a body of the request. The @RequestBody parameter can be treated as any other parameter in a @RequestMapping method and therefore it can also be validated by a standard validation mechanism.

 

Simple validation

Spring offers the simplest form of validation. we can specify if a particular parameter( PathVariable or RequestParameter) is required or not. By Default, Both are Required but we can easily change it to optional:

 

    @GetMapping("/person/{name}")
    public ResponseEntity hello(@PathVariable(value = "name", required = true) String name){
        //...
    }
 
    @GetMapping("/person")
    public ResponseEntity queryPerson(@RequestParam(value = "query", required = false) String query) {
        // ...
    }

 

Request body Validation

 

Validating Request body with some complex objects that represent a parsed JSON we have to do a bit more. First, we have to interpret our object with all the constraints and requirements. Spring has support for JSR 303 Bean Validation which makes it really easy. We just annotate our fields, with @NotBlank, @NotEmpty, @Pattern, @Max, @Min annotations with desired parameters. If there is some nested objects, then we have to add Valid annotation on a field with this objects, so that it will be validated. We can Use @Valid Or @validate for request body Validation. Spring supports 2 validation methods: Spring validation and JSR-303 bean validation.

 

@valid: Spring 3 provides support for declarative validation with JSR-303. If a JSR-303 provider, such as Hibernate Validator, is present on your classpath then This support enabled automatically. When enabled, you can trigger validation simply by annotating a Controller method parameter with the @Valid annotation:

 

@validated: @Validated was added to support "validation groups", That is a group of fields in the validated bean. It can be used in multi-step forms where you may validate name, email, etc. I will post a blog on Validation Groups sooner.

 

Request body Validation  For List

 

@Valid And @Validated both Annotation validate Java beans only, But @valid And @Validated Not Work For List<T> of Java Class, So To Validate  JSON of List what we have to do is We have To Modify Our Request Body For Validation. What We Are Going To Do in This Article is, First We create a generic class which validates Request Body.

 

Lets Create Class With Name Product :

 

@Entity
public class Product{

@Id
private Integer id;

@NotBlank(message="Product name Can not be empty")
private String name;

// getter setter

}

 

Let us Create JSON for Product And Save Products List : 

[
  {
        "name":""
  }
,{
	"name":"Titan G45"
 }
,{
	"name":"IPhone 6s"
 }
]

 

@PostMapping("/product/savelist")
public ResponseEntity<product> saveProducList(@Valid @RequestBody List<product> products)
{
 productService.saveProducts(products);
}

 

Response  :

 

"message" : "Data Save Successfuly"

"success" : true

 

So Validation didn't work for List of Product, But if  Our Request Body is Simple java Bean or a single Product then validation work for JSON. To validate List What we Have to Do is :

 

1. Create Class with name ValidateRequestBodyList 

 

As We know using @Valid with @RequestBody not going to validate Request Body of List<Product> in Controller so To Validate List what we have to do is create Simple class With Type Parameter   " T " So that we use this class to validate all request where our request body is a list.

 

public class ValidateRequestBodyList<T> {


    @Valid
    private List<T> requestBody;

    public List<T> getRequestBody() {
        return requestBody;
    }

    public void setRequestBody(List<T> requestBody) {
        this.requestBody = requestBody;
    }

    public ValidateRequestBodyList(List<T> requestBody) {
        this.requestBody = requestBody;
    }

    public ValidateRequestBodyList() {
    }
}



 

2.Use Of ValidateRequestBodyList

 

ValidateRequestBodyList Class is Generic Class which validate List Of Request Body, Now  What we have to do is Just Pass Class Name as Type Parameter And Validate Request Body Using @Valid. Now @Valid Is Going To Work And Validate Request Body.

 

@PostMapping("/product/savelist")
public ResponseEntity<product> saveProducList(@Valid @RequestBody ValidateRequestBodyList<product> products){

List<Product> productList= products.getRequestBody();

     productService.saveProducts(productList);      or //   productService.saveProducts(products.getRequestBody());   
}

 

Let us Create JSON for Product Again And Save Products List : 

 

{
   "requestBody":[
   {
     "name":""
   }
 , {
	"name":"Titan G45"
   }
 ,{
	"name":"IPhone 6s"
   }]
}

 

Response  :

 

"message" : null

"success" : false

"errors": [
    {
      "fieldName": "requestBody[0].title",
      "fieldError": "Product name Can not be empty"
    }
]

 

Suppose we have Class Person Which Contain List of  Products Then to validate List Of Product What We Have To Do Is Simply Put @Valid On List Of Product :

 

public class Person{

@Id
private Integer id;
@NotBlank(message="Email Id cant'be empty")
private String email;

@Valid                                       //to validate Product list annotate @valid for list
private List products;

}

About Author

Author Image
Bobby Sharma

Bobby is a Java Developer experienced in spring boot , Hibernate ,JPA , MYSQL , MongoDB , Servlets ,Java server pages ,Collections Framework.

Request for Proposal

Name is required

Comment is required

Sending message..