Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC Rest Service Controller with Error Handling done right?

Tags:

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 possible. Also i'd like to make use of HTTP Error codes so my Clients can act accordingly.

I was wondering how to implement my Methods, so they return JSON if everything works fine(in the body of the response) or toss a http error code as well as a custom reason why it didnt work(maybe errors that came from the DAO or the database). However I'm not sure which one is the right way? return a String and add the values to return to a Model, or return a HashMap and put my stuff in there? or return the objects directly? but then what if an error occures and i cannot return said Class? return null instead? I post 2-3 ways of doing it that i could imagine:

@RequestMapping(value="/addUser", method= RequestMethod.POST) public String addUser(@RequestBody User user, HttpServletResponse response, Model model) throws Exception{      try{         userService.addUser(user);         model.addAttribute("user", userService.getUser(user.getUsername(), user.getPassword()));         return "user";     }catch(Exception e){         model.addAttribute("error", e.toString());         response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());         return "error";     } } 

Or rather this way:

@RequestMapping(value="/addUser", method= RequestMethod.POST) public @ResponseBody Map addUser(@RequestBody User user, HttpServletResponse response){     Map map = new HashMap();     try{         userService.addUser(user);         map.put("success", true);         map.put("username", user.getUsername());     }catch (KeyAlreadyExistsException e){         map.put("success", false);         map.put("Error", e.toString());         response.sendError(HttpServletResponse.SC_FORBIDDEN, e.toString());     }catch(Exception e){         map.put("success", false);         map.put("Error", e.toString());         response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());     }     finally {         return map;     } } 

I realize code is not "just right" but i cannot figure out how to make it the way it needs to be. Maybe some experiences responses would help? Thx for the support already

like image 817
pascalwhoop Avatar asked Apr 30 '13 08:04

pascalwhoop


People also ask

How do you handle errors in rest?

The simplest way we handle errors is to respond with an appropriate status code. Here are some common response codes: 400 Bad Request – client sent an invalid request, such as lacking required request body or parameter. 401 Unauthorized – client failed to authenticate with the server.

What is the difference between ControllerAdvice and RestControllerAdvice?

The differences between @RestControllerAdvice and @ControllerAdvice is : @RestControllerAdvice = @ControllerAdvice + @ResponseBody . - we can use in REST web services. @ControllerAdvice - We can use in both MVC and Rest web services, need to provide the ResponseBody if we use this in Rest web services.


1 Answers

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.

like image 58
marco.eig Avatar answered Oct 08 '22 14:10

marco.eig