4

I have the following

web.xml

<error-page>
    <error-code>500</error-code>
    <location>/WEB-INF/views/errorPages/500.jsp</location>
</error-page>

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/WEB-INF/views/errorPages/error.jsp</location>
</error-page>

<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/WEB-INF/views/errorPages/500.jsp</location>
</error-page>

spring-context.xml

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
    <props>
        <prop key="java.lang.Exception">error</prop>
    </props>
    </property>
</bean>

<bean id="exceptionResolver"
    class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

    <property name="exceptionMappings">
        <props>
            <prop key="com.company.server.exception.GenericException">GenericExceptionPage</prop>
            <prop key="java.lang.Exception">error</prop>
        </props>
    </property>

    <property name="defaultErrorView" value="defaulterror"></property>
</bean>

<bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/views/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean> 

GenericException.java

public class GenericException extends RuntimeException
{
  private static final long serialVersionUID = 1L;

  private String customMsg;
  public String message;

  public String getCustomMsg()
  {
    return customMsg;
  }

  public void setCustomMsg(String customMsg)
  {
    this.customMsg = customMsg;
  }

  public GenericException(String customMsg)
  {
    this.customMsg = customMsg;
  }

  @Override
  public String getMessage()
  {
    return message;
  }

}

myController.java

@Controller
@RequestMapping(value = "/admin/store")
public class AdminController
{


 //bunch of restful drivin requestMappings


}

Question: How do I get any and all internal server errors & exceptions to display the exception/error message to a single page?

stackoverflow
  • 18,348
  • 50
  • 129
  • 196

2 Answers2

11

I would consider using the @ExceptionHandler annotation on a method in my controller. This annotation marks a method to be invoked by Spring when an Exception bubbles its way up past the controller.

This way, when one of your @RequestMapping methods throws an Exception, then this method will be invoked and can return whatever error message you would like.

public class BaseController {
    @ExceptionHandler(Throwable.class)
    public String handleException(Throwable t) {
        return "redirect:/errorPages/500.jsp";
    }

    @ExceptionHandler(Exception.class)
    public String handleException(Throwable t) {
        return "redirect:/errorPages/error.jsp";
    }
}

@Controller
@RequestMapping(value = "/admin/store")
public class AdminController extends BaseController
{
    @RequestMapping(...)
    //Some method

    @RequestMapping(...)
    //Another method
}
nicholas.hauschild
  • 42,483
  • 9
  • 127
  • 120
  • Given that you want to catch all exceptions throughout your application; would you need to create an @ExceptionHandler for each controller being used? – stackoverflow Oct 04 '12 at 13:09
  • 1
    You could use a common base class to hold the `@ExceptionHandler` annotated method. – nicholas.hauschild Oct 04 '12 at 13:13
  • I'm a bit of newb with Spring. Could you offer a generic example or point me to example of someone else doing this. Thanks greatly nicholas.hauschild – stackoverflow Oct 04 '12 at 13:16
  • 1
    I updated my example to show how you could do it. Notice that `AdminController` extends `BaseController`, and that `BaseController` is where the `@ExceptionHandler` annotated methods live. – nicholas.hauschild Oct 04 '12 at 13:20
3

If you want to handle exceptions from all your controllers you really should extend SimpleMappingExceptionResolver or, alternatively, AbstractHandlerExceptionResolver and configure it in the container as mentioned here.

This will prevent you (or others working in the code) from having to subclass all the controllers along with a single place to deal with exceptions.

Using the annotations and superclass will work but the annotation seems to be targeted more at per controller use.

Additionally both of these suggestions only work for exceptions thrown out of controller methods.

If you are concerned about exceptions from .jsp files than this post should give an complementary solution.

None of the above is a replacement for the web.xml error page configuration as their scope isn't the same. For a discussion this post seems like a good starting point.

Community
  • 1
  • 1
Aj-itator
  • 211
  • 3
  • 6