Spring Boot Validation Annotation
Others StoryProgramming

Spring Boot – Standard Validation Annotation

    1. Overview

    When build some rest controller, input / request validation is needed to ensure the value is valid. In this tutorial, i will explain step by step how to make simple validation for a Rest Controller use annotation in Spring Boot


    2. Maven Dependencies

    Basically, just need new dependency below to use validation annotation

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    3. Simple Object Request

    @Data
    @Builder
    public class ProfileReq implements Serializable {
    
        @NotBlank(message = "null")
        @Length(min = 3, max = 30, message = "between 3-30 characters")
        private String name;
    
        @NotNull(message = "null")
        @Min(value = 5, message = "minimum 5")
        @Max(value = 70, message = "maximum 70")
        private Integer age;
    }

    To make it simple, i only use 2 type of data String and Integer with constraint can not be null, name length must be between 3 and 30 characters, age value must be between 5 and 70.


    4. Implement Validation in Rest Controller

    @RestController
    public class SimpleController {
    
        @PostMapping(value = "/submit/profile")
        public ApiResponse<ProfileResp> submitProfile(@RequestBody @Valid ProfileReq req) {
            ProfileResp profile = ProfileResp.builder().name(req.getName()).age(req.getAge()).build();
    
            return ApiResponse.success(profile);
        }
    }

    Spring Boot really make complex process to really simple implementation through @Valid annotation

    When Spring Boot finds an argument annotated with @Valid, it automatically bootstraps the default JSR 380 implementation — Hibernate Validator — and validates the argument. When the target argument fails to pass the validation, Spring Boot throws a MethodArgumentNotValidException exception.


    5. Handle Exception

    @ControllerAdvice
    public class GlobalExceptionHandlerAdvisor {
    
    	@ExceptionHandler(value = {MethodArgumentNotValidException.class})
    	@ResponseBody
    	public ApiResponse<Void> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
    		FieldError fieldError = e.getBindingResult().getFieldError();
    		String fieldName = fieldError.getField();
    		String message = fieldName.concat(" - ").concat(fieldError.getDefaultMessage());
    		return ApiResponse.error(999, message);
    	}
    }
    
    RESPONSE WILL BE LIKE :
    {
        "success": false,
        "error": {
            "code": 999,
            "message": "age - maximum 70"
        }
    }

    We specified the MethodArgumentNotValidException exception as the exception to be handled. You can list all error messages directly into single message response ( like example below ) or only return single error message ( like example above ).

    Then simply just return response API, in my example, i use class object ApiResponse as standard response and return error response.

    @ControllerAdvice
    public class GlobalExceptionHandlerAdvisor {
    
    	@ExceptionHandler(value = {MethodArgumentNotValidException.class})
    	@ResponseBody
    	public ApiResponse<Void> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
    		StringBuilder message = new StringBuilder();
    		e.getBindingResult().getAllErrors().forEach((error) -> {
    			String fieldName = ((FieldError) error).getField();
    			String errorMessage = error.getDefaultMessage();
    			message.append(fieldName).append(" - ").append(errorMessage).append(", ");
    		});
    		return ApiResponse.error(999, message.toString());
    	}
    }
    
    RESPONSE WILL BE LIKE :
    {
        "success": false,
        "error": {
            "code": 999,
            "message": "name - null, age - null, "
        }
    }

    @RestController
    public class SimpleController {
    
        @PostMapping(value = "/submit/profile")
        public ApiResponse<ProfileResp> submitProfile(@RequestBody @Valid ProfileReq req) {
            ProfileResp profile = ProfileResp.builder().name(req.getName()).age(req.getAge()).build();
    
            return ApiResponse.success(profile);
        }
    }

    6. Conclusion and Github Link

    in this tutorial, i have explained how to make simple validation use annotation in Spring Boot Application. The simple flow is the REST controller allows us to easily accept JSON requests with different endpoints, validate Object Request, and send the responses in JSON format.

    You can access sample application through this link -> Github Link

    frenkeyblog
    the authorfrenkeyblog
    Part Time Blogger, Full Time Programmer
    Biar penulis tetap selalu semangat menulis artikel seputar travelling, mohon support nya dengan membelikan gue sepiring nasi padang dan segelas es cendol ya :-)Klik link Nihbuatjajan di bawah ya, Thank in Advance!

    Leave a Reply