Just for the sake of an example let's assume I want to create a REST endpoint which returns the message of the day (motd). The incoming parameter is the day represented by a number, the outcome is JSON which contains the day and the message.
public class Motd {
int day;
String message;
...
}
This gets translated into ...
{
"day": 1,
"message": "whatever you want to say here"
}
... and is returned by this code:
@RequestMapping(value = "/motd", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Motd> getMotd(@RequestParam(value = "day") int day {
...
return new ResponseEntity<Motd>(motd, HttpStatus.OK);
}
This works fine as long everything is ok but my intention is to return both a http status code and a JSON explaining the reason for any errors that might occur:
...
if( day > 365 ) {
Status error = new Status( "failed", "can't go beyond 365 days" );
return new ResponseEntity<Status>(error, HttpStatus.BAD_REQUEST);
}
...
But this conflicts with the ResponseEntity<Motd>
defined earlier. The only solution I know so far is to define ResponseEntity<String>
and serialize the JSON on my own.
Are there any alternatives / more elegant alternatives which allow Spring return "varying" classes ?
The emphasis of my question is not on error handling, I was shown some clever ways to do this based on exceptions for example. And if possible I want to avoid deriving all possible returned classes from a common base class.
My code is based on Spring Boot 1.3 RC1.
In the case of ResponseEntity
, Spring MVC does not care about the parameterized return type, it cares only about the value.
You can simply provide
public ResponseEntity<?> getMotd(@RequestParam(value = "day") int day {
Spring MVC's HttpEntityMethodProcessor
, which handles values returned by your handler methods that are of type ResponseEntity
, will retrieve the body
of the ResponseEntity
and delegate writing to the response to an appropriate HttpMessageConverter
.
The same process will happen for an Motd
value as it will for a Status
value.