Merge pull request #14784 from niket17590/feature/BAEL-6695-BooleanValidation
BAEL-6695 Boolean Validation in Spring Boot
This commit is contained in:
		
						commit
						c2522bf470
					
				| @ -105,6 +105,7 @@ | ||||
|         <module>spring-boot-documentation</module> | ||||
|         <module>spring-boot-3-url-matching</module> | ||||
|         <module>spring-boot-graalvm-docker</module> | ||||
|         <module>spring-boot-validations</module> | ||||
|     </modules> | ||||
| 
 | ||||
|     <dependencyManagement> | ||||
|  | ||||
							
								
								
									
										35
									
								
								spring-boot-modules/spring-boot-validations/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								spring-boot-modules/spring-boot-validations/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|         <groupId>com.baeldung.spring-boot-modules</groupId> | ||||
|         <artifactId>spring-boot-modules</artifactId> | ||||
|         <version>1.0.0-SNAPSHOT</version> | ||||
|     </parent> | ||||
|     <artifactId>spring-boot-validations</artifactId> | ||||
|     <name>spring-boot-validations</name> | ||||
|     <description>Demo of Validations in Spring Boot</description> | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-web</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-validation</artifactId> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|                 <artifactId>spring-boot-maven-plugin</artifactId> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| </project> | ||||
| @ -0,0 +1,12 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class Application { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(Application.class, args); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,33 @@ | ||||
| package com.baeldung.controller; | ||||
| 
 | ||||
| import javax.validation.Valid; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.http.ResponseEntity; | ||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| 
 | ||||
| import com.baeldung.dto.BooleanObject; | ||||
| import com.baeldung.service.ValidationService; | ||||
| 
 | ||||
| @RestController | ||||
| public class ValidationController { | ||||
| 
 | ||||
|     @Autowired | ||||
|     ValidationService service; | ||||
| 
 | ||||
|     @PostMapping("/validateBoolean") | ||||
|     public ResponseEntity<String> processBooleanObject(@RequestBody @Valid BooleanObject booleanObj) { | ||||
|         return ResponseEntity.ok("BooleanObject is valid"); | ||||
|     } | ||||
| 
 | ||||
|     @PostMapping("/validateBooleanAtService") | ||||
|     public ResponseEntity<String> processBooleanObjectAtService() { | ||||
|         BooleanObject boolObj = new BooleanObject(); | ||||
|         boolObj.setBoolField(Boolean.TRUE); | ||||
|         boolObj.setTrueField(Boolean.FALSE); | ||||
|         service.processBoolean(boolObj); | ||||
|         return ResponseEntity.ok("BooleanObject is valid"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,37 @@ | ||||
| package com.baeldung.controlleradvice; | ||||
| 
 | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import javax.validation.ConstraintViolationException; | ||||
| 
 | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.web.bind.MethodArgumentNotValidException; | ||||
| import org.springframework.web.bind.annotation.ExceptionHandler; | ||||
| import org.springframework.web.bind.annotation.ResponseStatus; | ||||
| import org.springframework.web.bind.annotation.RestControllerAdvice; | ||||
| 
 | ||||
| @RestControllerAdvice | ||||
| public class GlobalExceptionHandler { | ||||
| 
 | ||||
|     @ExceptionHandler(MethodArgumentNotValidException.class) | ||||
|     @ResponseStatus(value = HttpStatus.BAD_REQUEST) | ||||
|     public String handleValidationException(MethodArgumentNotValidException ex) { | ||||
|         return ex.getBindingResult() | ||||
|             .getFieldErrors() | ||||
|             .stream() | ||||
|             .map(e -> e.getDefaultMessage()) | ||||
|             .collect(Collectors.joining(",")); | ||||
|     } | ||||
| 
 | ||||
|     @ExceptionHandler(IllegalArgumentException.class) | ||||
|     @ResponseStatus(value = HttpStatus.BAD_REQUEST) | ||||
|     public String handleIllegalArugmentException(IllegalArgumentException ex) { | ||||
|         return ex.getMessage(); | ||||
|     } | ||||
| 
 | ||||
|     @ExceptionHandler(ConstraintViolationException.class) | ||||
|     @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) | ||||
|     public String handleConstraintViolationException(ConstraintViolationException ex) { | ||||
|         return ex.getMessage(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package com.baeldung.deserializer; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import com.fasterxml.jackson.core.JsonParser; | ||||
| import com.fasterxml.jackson.databind.DeserializationContext; | ||||
| import com.fasterxml.jackson.databind.JsonDeserializer; | ||||
| 
 | ||||
| public class BooleanDeserializer extends JsonDeserializer<Boolean> { | ||||
|     @Override | ||||
|     public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException { | ||||
|         String value = parser.getText(); | ||||
|         if (value != null && value.equals("+")) { | ||||
|             return Boolean.TRUE; | ||||
|         } else if (value != null && value.equals("-")) { | ||||
|             return Boolean.FALSE; | ||||
|         } else { | ||||
|             throw new IllegalArgumentException("Only values accepted as Boolean are + and -"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,56 @@ | ||||
| package com.baeldung.dto; | ||||
| 
 | ||||
| import javax.validation.constraints.AssertFalse; | ||||
| import javax.validation.constraints.AssertTrue; | ||||
| import javax.validation.constraints.NotNull; | ||||
| 
 | ||||
| import com.baeldung.deserializer.BooleanDeserializer; | ||||
| import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||||
| 
 | ||||
| public class BooleanObject { | ||||
| 
 | ||||
|     @NotNull(message = "boolField cannot be null") | ||||
|     Boolean boolField; | ||||
| 
 | ||||
|     @AssertTrue(message = "trueField must have true value") | ||||
|     Boolean trueField; | ||||
| 
 | ||||
|     @NotNull(message = "falseField cannot be null") | ||||
|     @AssertFalse(message = "falseField must have false value") | ||||
|     Boolean falseField; | ||||
| 
 | ||||
|     @JsonDeserialize(using = BooleanDeserializer.class) | ||||
|     Boolean boolStringVar; | ||||
| 
 | ||||
|     public Boolean getBoolField() { | ||||
|         return boolField; | ||||
|     } | ||||
| 
 | ||||
|     public void setBoolField(Boolean boolField) { | ||||
|         this.boolField = boolField; | ||||
|     } | ||||
| 
 | ||||
|     public Boolean getTrueField() { | ||||
|         return trueField; | ||||
|     } | ||||
| 
 | ||||
|     public void setTrueField(Boolean trueField) { | ||||
|         this.trueField = trueField; | ||||
|     } | ||||
| 
 | ||||
|     public Boolean getFalseField() { | ||||
|         return falseField; | ||||
|     } | ||||
| 
 | ||||
|     public void setFalseField(Boolean falseField) { | ||||
|         this.falseField = falseField; | ||||
|     } | ||||
| 
 | ||||
|     public Boolean getBoolStringVar() { | ||||
|         return boolStringVar; | ||||
|     } | ||||
| 
 | ||||
|     public void setBoolStringVar(Boolean boolStringVar) { | ||||
|         this.boolStringVar = boolStringVar; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package com.baeldung.service; | ||||
| 
 | ||||
| import javax.validation.Valid; | ||||
| 
 | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| 
 | ||||
| import com.baeldung.dto.BooleanObject; | ||||
| 
 | ||||
| @Service | ||||
| @Validated | ||||
| public class ValidationService { | ||||
| 
 | ||||
|     public void processBoolean(@Valid BooleanObject booleanObj) { | ||||
|         // further processing | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,125 @@ | ||||
| package com.baeldung.controller; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.junit.jupiter.api.extension.ExtendWith; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||||
| import org.springframework.boot.test.context.TestConfiguration; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.test.context.junit.jupiter.SpringExtension; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| 
 | ||||
| import com.baeldung.service.ValidationService; | ||||
| 
 | ||||
| @ExtendWith(SpringExtension.class) | ||||
| @WebMvcTest(controllers = ValidationController.class) | ||||
| class ValidationControllerUnitTest { | ||||
| 
 | ||||
|     @Autowired | ||||
|     private MockMvc mockMvc; | ||||
| 
 | ||||
|     @TestConfiguration | ||||
|     static class EmployeeServiceImplTestContextConfiguration { | ||||
|         @Bean | ||||
|         public ValidationService validationService() { | ||||
|             return new ValidationService() { | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Autowired | ||||
|     ValidationService service; | ||||
| 
 | ||||
|     @Test | ||||
|     void whenNullInputForBooleanField_thenHttpBadRequestAsHttpResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":null,\"trueField\":true,\"falseField\":false,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andExpect(status().isBadRequest()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenInvalidInputForTrueBooleanField_thenErrorResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":false,\"falseField\":false,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         String output = mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andReturn() | ||||
|             .getResponse() | ||||
|             .getContentAsString(); | ||||
| 
 | ||||
|         assertEquals("trueField must have true value", output); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenInvalidInputForFalseBooleanField_thenErrorResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":true,\"falseField\":true,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         String output = mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andReturn() | ||||
|             .getResponse() | ||||
|             .getContentAsString(); | ||||
| 
 | ||||
|         assertEquals("falseField must have false value", output); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenInvalidBooleanFromJson_thenErrorResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":true,\"falseField\":false,\"boolStringVar\":\"plus\"}"; | ||||
| 
 | ||||
|         String output = mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andReturn() | ||||
|             .getResponse() | ||||
|             .getContentAsString(); | ||||
| 
 | ||||
|         assertEquals("Only values accepted as Boolean are + and -", output); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenAllBooleanFieldsValid_thenCorrectResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":true,\"falseField\":false,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         String output = mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andReturn() | ||||
|             .getResponse() | ||||
|             .getContentAsString(); | ||||
| 
 | ||||
|         assertEquals("BooleanObject is valid", output); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenAllBooleanFieldsValid_whenServiceValidationFails_thenErrorResponse() throws Exception { | ||||
|         mockMvc.perform(post("/validateBooleanAtService").contentType("application/json")) | ||||
|             .andExpect(status().isInternalServerError()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenNullInputForTrueBooleanField_thenCorrectResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":null,\"falseField\":false,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andExpect(status().isOk()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void whenNullInputForFalseBooleanField_thenHttpBadRequestAsHttpResponse() throws Exception { | ||||
|         String postBody = "{\"boolField\":true,\"trueField\":true,\"falseField\":null,\"boolStringVar\":\"+\"}"; | ||||
| 
 | ||||
|         String output = mockMvc.perform(post("/validateBoolean").contentType("application/json") | ||||
|             .content(postBody)) | ||||
|             .andReturn() | ||||
|             .getResponse() | ||||
|             .getContentAsString(); | ||||
| 
 | ||||
|         assertEquals("falseField cannot be null", output); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,21 @@ | ||||
| package com.baeldung.dto; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| class BooleanUnitTest { | ||||
| 
 | ||||
|     @Test | ||||
|     void givenInputAsString_whenStringToBoolean_thenValidBooleanConversion() { | ||||
|         assertEquals(Boolean.TRUE, Boolean.valueOf("TRUE")); | ||||
|         assertEquals(Boolean.FALSE, Boolean.valueOf("false")); | ||||
|         assertEquals(Boolean.TRUE, Boolean.parseBoolean("True")); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     void givenInputAsboolean_whenbooleanToBoolean_thenValidBooleanConversion() { | ||||
|         assertEquals(Boolean.TRUE, Boolean.valueOf(true)); | ||||
|         assertEquals(Boolean.FALSE, Boolean.valueOf(false)); | ||||
|     } | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user