I use Tomcat 7 and Lo4j for all my server logs and GWT for client (only AJAX calls). All my unhandled exceptions get logged in my catalina.log.
Now I want to catch all exceptions and add some of the user's specific Tomcat SessionData.
There are several ways:
What would be the best way to achieve this?
Out of what I understood from your question, you can try to use at least one of two ways:
If you have access to the source code of all of your servlets, you can make a little refactoring using a basic super-servlet that is responsible for the logging/whatever of every request working transparently with AJAX, no error forwards directives, and no global exception handlers. Suppose you use service(ServletRequest,ServletResponse)
as the servlet entry point (but you can do the following for every do*()
method either), then you can create an abstract super-servlet and simply inherit your servlets from it.
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>stackoverflow.Servlet1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>stackoverflow.Servlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>servlet1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>servlet2</url-pattern>
</servlet-mapping>
public abstract class BasicServlet extends HttpServlet {
/**
* Won't let it be {@code abstract} - we don't want to force any sub-servlet to implement this method.
*/
protected void doService(ServletRequest request, ServletResponse response) {
}
@Override
public final void service(ServletRequest request, ServletResponse response) {
try {
doService(request, response);
} catch ( Throwable ex ) {
err.println(ex.getMessage());
}
}
}
public final class Servlet1 extends BasicServlet {
@Override
protected void doService(ServletRequest request, ServletResponse response) {
out.println("I'm servlet #1");
}
}
public final class Servlet2 extends BasicServlet {
@Override
protected void doService(ServletRequest request, ServletResponse response) {
out.println("I'm servlet #2");
}
}
An advantage of this method is that you do not need to configure anything else than changing your servlet classes and not depend on the external configuration or context. The disadvantage is that you always must extend BasicServlet
.
I didn't actually test it right now, for more information please see http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html . Filters allow to intercept each request (we use such a filter implementation for our JSPs while debugging and writing the exceptions into the common log file). The disadvantage is that it's not guaranteed that the filter can cover every exception/case, for example if any filter preceded your own filter.
<filter>
<filter-name>exceptionLoggingFilter</filter-name>
<filter-class>stackoverflow.ExceptionLoggingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>exceptionLoggingFilter</filter-name>
<url-pattern>*</url-pattern> <!-- we will process every request -->
</filter-mapping>
public final class ExceptionLoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) {
try {
filterChain.doFilter(request, response);
} catch ( Throwable ex ) {
err.println(ex);
}
}
@Override
public void destroy() {
}
}
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With