odedravijay
odedravijay

Reputation: 61

Spring MVC ExceptionHandler for restful and normal

I want to handle exception for both normal and rest/ajax requests. Here is my code,

@ControllerAdvice
public class MyExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleCustomException(Exception ex) {

        ModelAndView model = new ModelAndView("error");
        model.addObject("errMsg", ex.getMessage());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        sw.toString();
        model.addObject("errTrace", sw);
        return model;

    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleAjaxException(Exception ex) {
        JSONObject model = new JSONObject();
        model.put("status", "error");
        model.put("errMsg", ex.getMessage());
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        sw.toString();
        model.put("errTrace", sw);

        return model.toString();
    }
}

This will give me an error as I cant have @ExceptionHandler(Exception.class) twice. So what could be the solution?

Upvotes: 3

Views: 2502

Answers (4)

Mohd Yasin
Mohd Yasin

Reputation: 483

You can write two exception handler to handle both normal and rest/ajax requests exception. Here is sample code to illustrate the solution.

@ControllerAdvice(annotations = RestController.class)
@Order(1)
class RestExceptionHandler {
    @ExceptionHandler(MyException.class)
    @ResponseBody
    ResponseEntity<ErrorResponse> exceptionHandler() {
        ....
    }   
}

@ControllerAdvice(annotations = Controller.class)
@Order(2)
class ExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ModelAndView handleError500(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("error", "500");
        return mav;
    }
}

Upvotes: 0

Bogdan Samondros
Bogdan Samondros

Reputation: 158

You can create inner static class @RestControllerAdvice. Noot needed to create separated @RestController for this.

@ControllerAdvice
public class BaseController {
private static final Logger logger = 
LoggerFactory.getLogger(BaseController.class);

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleException(Exception error, Model model) {
    logger.error("Error was: " + error.getMessage(), error);
    model.addAttribute("message", error.getMessage());
    model.addAttribute("stackTrace", error.getStackTrace());
    model.addAttribute("exception", error);
    return "error"; //return view
}

@RestControllerAdvice
public static class RestBaseController {

    private static final Logger logger = LoggerFactory.getLogger(RestBaseController.class);

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleException(Exception error) {
        logger.error("Error was: " + error.getMessage(), error);

        return "error"; //return "error"
    }
}
}

Upvotes: 0

Anatoly Deyneka
Anatoly Deyneka

Reputation: 1258

see the configuration of @ControllerAdvice: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html

So you can create two classes(error handlers) and specify annotations/basePackages/assignibaleTypes

For example for REST(ajax) use @RestController annotation for your controllers and you can handle errors like this:

@ControllerAdvice(annotations = RestController.class)
public class MyExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleAjaxException(Exception ex) {
        ...
    }
}

for other cases it can be error handler with annotation

@ControllerAdvice(annotations = Controller.class)

Upvotes: 5

Charnjeet Singh
Charnjeet Singh

Reputation: 3107

This is global exception handler in spring mvc.this is called every time when exception found in your application.I think you to control only 404 exception with the help of web.xml.

@ControllerAdvice
public class GlobalExceptionController {

    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public ModelAndView handleAllException(Throwable ex,
            HttpServletResponse response) {

        ex.printStackTrace();
        // Set Status
        response.setStatus(500);
        // Set View
        ModelAndView model = new ModelAndView("500");
        model.addObject("navlabel", "");
        model.addObject("userActivity", new ArrayList<String>());
        // Set exception Message
        model.addObject("errMsg", ex.getMessage());
        return model;
    }
}

Upvotes: 2

Related Questions