I was wondering how to correctly implement a Spring Controller which is supposed to serve as a REST Service. Especially I want to try and make the interface as RESTful as po
you can use @ExceptionHandler
with @ControllerAdvice
check this link
use ResponseEntity class to exploit error with http status code.
You could try the following code:
@RequestMapping(value = "/profile", method = RequestMethod.GET)
@ResponseBody @ResponseStatus(value = HttpStatus.OK)
public ResponseEntity<UserVO> getUserProfile()
{
string userName = getUserAuthentication().getName();
if (StringUtils.isEmpty(userName)) RestUtil.defaultJsonResponse("");
User user = userService.getUserByUserNameWithCounters(userName);
return RestUtil.getJsonResponse(new UserVO(user));
}
If you want your whole Exception with stackTrace to be transmitted toward your client, as @Bart said you should send an "ErrorResource" object.
A library has it off-the-shelf :
<dependency>
<groupId>com.github.zg2pro</groupId>
<artifactId>spring-rest-basis</artifactId>
<version>0.2</version>
</dependency>
add it to your project and then just add a "@ControllerAdvice" class to your beans, as it is explained in the project wiki.
That should handle your errors nicely!
Firstly, I think you should always return a object when returning JSON. Even when something goes horribly wrong.
When something goes wrong you simply set response.setStatus()
and return a resource describing the error.
public class ErrorResource implements Resource {
private final int status;
private final String message;
public ErrorResource(int s, String m) {
status = s;
message = m;
}
public int getStatus() {
return status;
}
public String getMessage() {
return message;
}
}
The resource gets serialized and the outcome would be
{"status":500, "message":"Yay!"}
Using a Map
will work but I would like to advise you to write some resource classes which define the object to be returned. They would be easier to maintain. Maps
don't offer any structure while structure is a very important part when creating a REST service.
I don't think you should return a resource with the raw exception message embedded. It can potentially leak information you don't want anyone to see.
You could also catch your exceptions with @ExceptionHandler
annotated methos within your Rest Controller.
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleException(Exception e) {
return "return error object instead";
}
this will make your acutal controller/business logic cleaner.