In my request body I am passing parameter in different way to validate.
{
"name":[]
}
Here the operation is executing which I want to restrict with my custom error message.
Here I am getting 400 bad request so how to handle this with proper error message.
In my controller I had
if (myRequestResult.getName() == null || myRequestResult.getName().isEmpty()) {
throw new Exception();
} else {
myService.setName(myRequestResult.getName());
}
Which is working fine but Now I remove that and Using validator annotation.
@Data
public class MyResultRequest {
@NotEmpty(message = "List of name must not be empty")
@Size(min = 1, message = "List of name must have at least one element")
private List<String> name;
}
This is my restcontroller
@Log4j2
@RestController(value = "apiMyController")
@RequestMapping(path = "/api/v1/someRandomeURL")
@RequiredArgsConstructor(onConstructor = @__({@Autowired}))
public class ExecutionResultsController {
@RequestMapping(method = RequestMethod.POST)
public ExecutionResultDTO create(@RequestBody MyRequestResult myRequestResult) throws Exception {
myService.setName(myRequestResult.getName());
}
}
Can anybody tell me how to fix that as I am following this from here Doc
@seenukarthi is actually correct. You have to use @Valid
on the endpoint to valid the request body.
Note: The validation errors are not visible in the error response.
The error will appear in the console log. Example:
2023-11-20T13:12:13.057+05:30 WARN 85261 --- [nio-8081-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<java.lang.Object> com.example.TestController.create(com.example.MyRequestResult) with 2 errors: [Field error in object 'myRequestResult' on field 'name': rejected value [[]]; codes [NotEmpty.model.name,NotEmpty.name,NotEmpty.java.util.List,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [model.name,name]; arguments []; default message [name]]; default message [List of name must not be empty]] [Field error in object 'model' on field 'name': rejected value [[]]; codes [Size.model.name,Size.name,Size.java.util.List,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [model.name,name]; arguments []; default message [name],2147483647,1]; default message [List of name must have at least one element]] ]
Please look into the logs properly. It will be there.
Now, if you want to capture validation errors happened on request body and to include it to response, then you have to use org.springframework.validation.BindingResult
.
Let me show with an example:
Update ExecutionResultDTO
to have errors list also if possible :
@Data
public class ExecutionResultDTO {
private List<String> name;
private List<String> errors;
}
Updated controller that I have used for testing:
import jakarta.validation.Valid;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
public class TestController {
@PostMapping("create")
public ResponseEntity<ExecutionResultDTO> create(@Valid @RequestBody MyRequestResult myRequestResult, BindingResult bindingResult) {
ExecutionResultDTO dto = new ExecutionResultDTO();
dto.setName(myRequestResult.getName());
if (bindingResult.hasErrors()) {
dto.setErrors(bindingResult.getFieldErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.toList()));
return new ResponseEntity<>(dto, HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(dto, HttpStatus.CREATED);
}
}
Postman :
For Incorrect Data:
For Correct Data:
Change the logic accordingly. This is just an example.