0

In my current spring-boot project, I have this ExceptionHandler:

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
        if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
            throw error;

        ModelAndView mav = new ModelAndView();
        mav.setAttribute("error", error);
        return mav;
    }

}

What I want to do it's make this handler redirect to different error pages, depending of origin the error.

I have two "types" of pages in my project: a public one, acessed both by an anonymous user or an authenticated user, and the admin pages (private), acessed only by authenticated users.

This two types of page have different styles. I want, when an error occurs when the user is in the public pages, an error page with the public style be shown. If the errors occurs when the user is in the private pages, another error page, with the style of the private pages be shown.

Kleber Mota
  • 8,521
  • 31
  • 94
  • 188

2 Answers2

0

You can construct a selection of what exception classes it needs to throw in your controller , Assuming like this:

@RequestMapping(value = "/check")
 public ModelAndView processUser( ) throws Exception {
        ModelAndView modelAndView = new ModelAndView();

        if (something... ) {
            throw new GlobalDefaultExceptionHandler( );  // throws GlobalDefaultExceptionHandler
        }
        if (something else... ) {
            throw new AnotherExceptionHandler( );// throws 'anotherExceptionHandler'
        }

     // If there isn't exception thrown....do something

 }

And assuming this is the AnotherExceptionHandler class:

@ControllerAdvice
public class AnotherExceptionHandler{

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {
        if (AnnotationUtils.findAnnotation(error.getClass(), ResponseStatus.class) != null)
            throw error;

        // Go to another view
        ModelAndView mav = new ModelAndView();
        mav.setAttribute("anotherError", error);
        return mav;
    }

}

But if you are forced to use only an handler , you can just use selection directly just :

@ControllerAdvice
public class GlobalDefaultExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception error) throws Exception {

 ModelAndView mav =null;

        if ( // something...){
         mav = new ModelAndView()
         mav.setAttribute("error", ... );
         return mav;
          } 

         else if (// another something...){
           mav = new ModelAndView()
           mav.setAttribute("anotherError", ...);
           return mav;
          }

return mav;

}
Fevly Pallar
  • 3,059
  • 2
  • 15
  • 19
  • your last example accomplish what I want, I guess, but I still have questions about what should be the condicional expression used here. I have two controllers: MainController, where lies most of the mappings for the public views (and some of the private), and a generic controller with the mappings for the private views. Each class from the model layer have a controller derived from this generic controller. With this in mind, do you have any sugestions about what I should use in the condicional expresson? – Kleber Mota Sep 08 '15 at 16:51
  • The selection actually produces different `ModelAndView` object, so from there you can go to different pages by setting the view name (example `mav.setViewName("aPage")`) for each of those ModelAndView, but again this is just an example I won't never know your structures of views, controllers, exception classes, etc. That's the idea. – Fevly Pallar Sep 08 '15 at 18:08
0

There are several options. Some of them are:

  1. You can check if user has been authenticated by using request.getUserPrincipal(). The return value will be null if user is not authentcicated. Depending on the result, you can return a different view.

  2. Have all your Contollers service public pages extend from one PublicBaseController and controllers service private pages extend PrivateBaseController. Add method annotated with @ExceptionHandler to base controllers, which return appropriate views.

jny
  • 8,007
  • 3
  • 37
  • 56