MethodArgumentNotValidException not thrown - java

My controller looks like the following:
#RequestMapping(value = "/cars/{types}", method = RequestMethod.PUT,
headers = "Accept=application/json")
#ResponseStatus(HttpStatus.OK)
public void startEngine(
#PathVariable #Min(0) String types, #RequestBody #Valid someObject request, BindingResult result)
throws MethodArgumentNotValidException {
if(result.hasErrors())
{
System.out.println("Error");
//Should I be throwing MethodArgumentNotValidException here? And if so how? I don't know how to retrieve the first parameter for it's constructor (MethodParameter object)
}
//Controller code
}
So after I verify whether or not my result object encountered any errors during validation, how can I then throw the MethodArgumentNotValidException? Or should Spring be already throwing that exception during validation?

If I remember correctly, Spring should throw MethodArgumentNotValidException only if you have not provided an Errors (here, BindingResult) parameter for the #Valid annotated parameter.
You can throw it yourself if you would like to.

Related

MultipartFile custom annotations validation

I've a file upload validation that raises a BindException instead of a MethodArgumentNotValidException and I don't understand why.
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'patientProfileImageDTO' on field 'profileImage': rejected value [org.springframework.web.multipart.commons.CommonsMultipartFile#2840a305]; codes [CheckImageFormat.patientProfileImageDTO.profileImage,CheckImageFormat.profileImage,CheckImageFormat.org.springframework.web.multipart.MultipartFile,CheckImageFormat]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patientProfileImageDTO.profileImage,profileImage]; arguments []; default message [profileImage]]; default message [Invalid image format (allowed: png, jpg, jpeg)]
My Controller is:
#PostMapping("/patient/image")
public ResponseEntity<?> updateProfileImage(#Validated PatientProfileImageDTO patientProfileImageDTO)
and this is the PatientProfileImageDTO
public class PatientProfileImageDTO {
#CheckImageFormat
#CheckImageSize
private MultipartFile profileImage;
public MultipartFile getProfileImage() {
return profileImage;
}
public void setProfileImage(MultipartFile profileImage) {
this.profileImage = profileImage;
}
}
the CheckFormatImage and CheckImageSize validators are correctly invoked.
I need to catch these errors in my:
#ControllerAdvice
public class ApiExceptionHandler {
ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, WebRequest request) {
...
}
}
I've other custom validation annotations in another part of my code and they work as intended.
I mean:
#OldPasswordMatch(message = "old password mismatch")
private String oldPassword;
This custom validation triggers a MethodArgumentNotValidException that what I want.
What's wrong with my code?
Thanks.
There is also a BindException thrown by Spring MVC if an invalid object was created from the request parameters. MethodArgumentNotValidException is already a subclass of BindException.
These are actually intentionally different exceptions. #ModelAttribute, which is assumed by default if no other annotation is present, goes through data binding and validation, and raises BindException to indicate a failure with binding request properties or validating the resulting values. #RequestBody, on the other hand converts the body of the request via other converter, validates it and raises various conversion related exceptions or a MethodArgumentNotValidException if validation fails. In most cases a MethodArgumentNotValidException can be handled generically (e.g. via #ExceptionHandler method) while BindException is very often handled individually in each controller method.
You can process these errors separately or you can catch only the super class BindException.
#ExceptionHandler(BindException.class)
protected ResponseEntity<Object> handleBindException(BindException ex) {
// ..
}

How to get error list by using BindingResult for #Valid List

I have a Spring controller method that I wanna validate using #Valid and get the BindingResult errorlist. But In my #RequestBody have List list.
#PostMapping(path="/save/inouts")
public ResponseEntity<List<InoutResponse>> saveInouts(#Valid InoutWrapper inouts, BindingResults res){
.....
}
class InoutWrapper {
private List<Inouts> inoutList;
//getters and //setters
}
So I need to get error list as well as each error has the reference to Inout object to make InoutResponse.
You have 2 options, either remove the #valid annotation from the controller parameter and call the validation explicitly. Like below:
javax.validation.Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
final Set<ConstraintViolation<InoutWrapper>> constraints = validator.validate(inouts);
Or write an exception handler for your controller. I would prefer this one. Something like below:
#ControllerAdvice
class MyExceptionHandler extends ResponseEntityExceptionHandler {
#Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
// read ex.getBindingResult().
return super.handleMethodArgumentNotValid(ex, headers, status, request);
}
}

java.lang.annotation.AnnotationFormatError is happened when i use validation in spring mvc

When I'm using validation I get these errors. It finds the errors but when I return to the same jsp page again it throws these exception, otherwise it works. Any suggestions would be appreciated.
This is happening because you may have defined groups and payload as #NotNull annotation in your entity.
And your form submission is not submitting any value for that so it is going null and because of that your are getting these errors.
Better to define BindingResult and control on errors like below.
#RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(#Valid EntityPojo entity, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
return getPath() + "/update"; //here you return the same page with errors
}
//here you proceed further if there is no error
}

REST Handling a wrong Parameter and required parameter

My requirement is to get the json response with customized error message when a required #RequestParam is not sent to the request handler or invalid parameter(required is int but user is passing string) is sent to the request handler.
currently I am trying to use the #Exceptionhandler mechanism to handle these exceptions. But the respective exception handler methods not getting invoked.
Please see the code snippet:
#Controller
#RequestMapping("api/v1/getDetails")
public class Abc {
#RequestMapping
#ResponseBody
public Envelope<Object> retrieveTransactions(#RequestParam(required = false) Integer a,
#RequestParam int b, #RequestParam(required = false) boolean c,
HttpServletRequest req) {`
//implementation goes here
}
#ExceptionHandler(MissingServletRequestParameterException.class)
#ResponseBody
public Envelope<Object> missingParameterExceptionHandler(Exception exception,
HttpServletRequest request) {
Envelope<Object> envelope = null;
//error implementation
return envelope;
}
#ExceptionHandler(TypeMismatchException.class)
#ResponseBody
public Envelope<Object> typeMismatchExpcetionHandler(Exception exception, HttpServletRequest request) {
Envelope<Object> envelope = null;
//error implementation
return envelope;
}
Do I need to configure anything extra for exception handler? can anyone tell me where I am doing the wrong.
Consider identifying the parameter name in the RequestParameter annotation.
For example
#RequestParam(value="blammy", required=false)
I've never bothered figuring out how to handle type mismatch,
instead I've found it easier to accept all parameters as String and perform all verification myself (including type).
Also,
If you are accepting the HttpServletRequest as a parameter to your handler,
then there is no need to use #RequestParam annotations,
just get the parameter values directly from the request.
Finally,
consider org.springframework.web.context.request.WebRequest
or org.springframework.web.context.request.NativeWebRequest
instead of HttpServletRequest.
Have you tried to use MethodArgumentNotValidException or HttpMessageNotReadableException instead on your handlers?
And put required = true on your #RequestParam declaration to catch missing params exceptions
#RequestParam(required = true)

How to handle validation errors and exceptions in a RESTful Spring MVC controller?

For example, how to handle validation errors and possible exceptions in this controller action method:
#RequestMapping(method = POST)
#ResponseBody
public FooDto create(#Valid FooDTO fooDto, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return null; // what to do here?
// how to let the client know something has gone wrong?
} else {
fooDao.insertFoo(fooDto); // What to do if an exception gets thrown here?
// What to send back to the client?
return fooDto;
}
}
Throw an exception if you have an error, and then use #ExceptionHandler to annotate another method which will then handle the exception and render the appropriate response.
#RequestMapping(method = POST)
#ResponseBody
public FooDto create(#Valid FooDTO fooDto) {
//Do my business logic here
return fooDto;
}
Create a n exception handler:
#ExceptionHandler( MethodArgumentNotValidException.class)
#ResponseBody
#ResponseStatus(value = org.springframework.http.HttpStatus.BAD_REQUEST)
protected CustomExceptionResponse handleDMSRESTException(MethodArgumentNotValidException objException)
{
return formatException(objException);
}
I don't know if this is the correct approach i am following. I would appreciate if you could tell me what you have done for this issue.

Categories

Resources