What is the good approach to forward the exception from servlets to a jsp page?

前端 未结 2 543
太阳男子
太阳男子 2020-12-03 16:31

I know I can put something in the web.xml like this

  
   java.lang.Throwable  
   

        
2条回答
  •  温柔的废话
    2020-12-03 17:03

    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.exeption
    • ERROR_EXCEPTION_TYPE - javax.servlet.error.exception_type
    • ERROR_MESSAGE - javax.servlet.error.message
    • ERROR_REQUEST_URI - javax.servlet.error.request_uri
    • ERROR_SERVLET_NAME - javax.servlet.error.servlet_name
    • ERROR_STATUS_CODE - javax.servlet.error.status_code

    So, 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;
    }
    

提交回复
热议问题