I know I can put something in the web.xml like this
java.lang.Throwable
The information about the exception is already available by several request attributes. You can find the names of all those attributes in the RequestDispatcher javadoc:
ERROR_EXCEPTION
- javax.servlet.error.exeptionERROR_EXCEPTION_TYPE
- javax.servlet.error.exception_typeERROR_MESSAGE
- javax.servlet.error.messageERROR_REQUEST_URI
- javax.servlet.error.request_uriERROR_SERVLET_NAME
- javax.servlet.error.servlet_nameERROR_STATUS_CODE
- javax.servlet.error.status_codeSo, in a nutshell, this JSP example should display all the possible exception detail:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
- Exception:
- Exception type:
- Exception message:
- Request URI:
- Servlet name:
- Status code:
Additionally, you could also show this useful information:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
...
- Timestamp:
- User agent:
The concrete Exception
instance itself is in the JSP only available as ${exception}
when you mark the page as an error page:
<%@ page isErrorPage="true" %>
...
${exception}
Only if you're using EL 2.2 or newer, then you can print its stacktrace as below:
<%@ page isErrorPage="true" %>
...
${pageContext.out.flush()}${exception.printStackTrace(pageContext.response.writer)}
Or if you're not on EL 2.2 yet, then create a custom EL function for that:
public final class Functions {
private Functions() {}
public static String printStackTrace(Throwable exception) {
StringWriter stringWriter = new StringWriter();
exception.printStackTrace(new PrintWriter(stringWriter, true));
return stringWriter.toString();
}
}
Which is registered in /WEB-INF/functions.tld
:
Custom Functions
1.0
http://example.com/functions
printStackTrace
com.example.Functions
java.lang.String printStackTrace(java.lang.Throwable)
And can be used as
<%@ taglib prefix="my" uri="http://example.com/functions" %>
...
${my:printStackTrace(exception)}
As to the logging of the exception, easiest place would be a filter which is mapped on an URL pattern of /*
and does basically the following:
try {
chain.doFilter(request, response);
} catch (ServletException e) {
log(e.getRootCause());
throw e;
} catch (IOException e) { // If necessary? Usually not thrown by business code.
log(e);
throw e;
}