Global servlet exception handling in OSGI. How?

Viewed 538

Is there a way to somehow globally handle unchecked exceptions in osgi (karaf) that were thrown in servlets?

What I mean is something like in Spring, where there is @ControllerAdvice where you can specify methods for each exception type and handle it.

I would like to unify the exception handling in my rest api that exposes osgi services.

1 Answers

Doing REST in OSGi

You mention REST and Servlets in this question. If you're using REST in OSGi then the JAX-RS Whiteboard is the easiest way to do things. If you want to use raw Servlets, then the Http Whiteboard is the way to go. Both models make it easy to handle exceptions.

Update

In an effort to make it easier for people to see how this works, I've created a working example on GitHub which covers Servlets and JAX-RS error handling.

Using the HTTP Whiteboard

The HTTP whiteboard allows servlets to be registered as OSGi services and then used to handle requests. One type of request handling is to act as an error page.

Error pages are registered with the osgi.http.whiteboard.servlet.errorPage property. The value of this property is one or more Strings containing either:

  • A fully qualified class name for an exception that should be handled
  • A three digit error code

The OSGi specification describes this in an example, and other pages list the attributes that you can use to work out what went wrong.

For example this servlet will be called for IOException, NullPointerException and for status codes 401 and 403:

@Component
@HttpWhiteboardServletErrorPage(errorPage = {"java.io.IOException", "java.lang.NullPointerException", "401", "403"})
public class MyErrorServlet extends HttpServlet implements Servlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws Exception {

        Throwable throwable = (Throwable) request
                .getAttribute("javax.servlet.error.exception");
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");

        // Do stuff with the error
    }

}

N.B. I have used OSGi R7 Component Property Type annotations to make this simpler to read. It will work with older versions of DS and the Http Whiteboard equally well.

Using the JAX-RS whiteboard

The JAX-RS Whiteboard allows you to use any of the JAX-RS extension types as a whiteboard service. In this case you want an ExceptionMapper.

In this example we add a handler for IOException

@Component
@JaxrsExtension
public class MyExceptionMapper implements ExceptionMapper<IOException> {
    Response toResponse(IOException e) {
        // Create a response
    }
}
Related