Reputation: 939
In my request handler I want to do some validation and based on the outcome of validation check I will return different response (success/error). So I create a abstract class for the response object and make 2 subclasses for failure case and successful case. The code looks something like this, but it doesn't compile, complaining that errorResponse and successResponse cannot be converted to AbstractResponse.
I'm quite new to Java Generic and Spring MVC so I don't know of a simple way to solve this.
@ResponseBody ResponseEntity<AbstractResponse> createUser(@RequestBody String requestBody) {
if(!valid(requestBody) {
ErrorResponse errResponse = new ErrorResponse();
//populate with error information
return new ResponseEntity<> (errResponse, HTTPStatus.BAD_REQUEST);
}
createUser();
CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
// populate with more info
return new ResponseEntity<> (successResponse, HTTPSatus.OK);
}
Upvotes: 18
Views: 38926
Reputation: 1978
There are two problems here:-
Your return type has to be changed to match the two response subclasses ResponseEntity<? extends AbstractResponse>
When you instantiate your ResponseEntity you cannot use the simplified <>
syntax you have to specify which response class you are going to use new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);
@ResponseBody ResponseEntity<? extends AbstractResponse> createUser(@RequestBody String requestBody) {
if(!valid(requestBody) {
ErrorResponse errResponse = new ErrorResponse();
//populate with error information
return new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);
}
createUser();
CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
// populate with more info
return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPStatus.OK);
}
Upvotes: 26
Reputation: 521
Another approach would be using error handlers
@ResponseBody ResponseEntity<CreateUserSuccessResponse> createUser(@RequestBody String requestBody) throws UserCreationException {
if(!valid(requestBody) {
throw new UserCreationException(/* ... */)
}
createUser();
CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse();
// populate with more info
return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK);
}
public static class UserCreationException extends Exception {
// define error information here
}
@ExceptionHandler(UserCreationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handle(UserCreationException e) {
ErrorResponse errResponse = new ErrorResponse();
//populate with error information from the exception
return errResponse;
}
This approach enables the possibility of returning any kind of object, so an abstract super class for the success case and the error case (or even cases) is no longer necessary.
Upvotes: 12