Struts2异常捕获与处理

最近更新STRUTS的版本到2.1.8 ,发现异常发生后,没有收到异常邮件了,
配置
<global-exception-mappings>
			<exception-mapping result="normalException"
				exception="com.esc.common.exception.BusinessException">
			</exception-mapping>
		</global-exception-mappings>

BusinessException继承了RuntimeExcption,2.0的时候,凡是非BusinessException子类,就会向外抛出,那么就能在我下面的catch块中捕获到异常
代码
//我的filter,在struts的filter之前
public void doFilter(ServletRequest org0, ServletResponse org1,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) org0;
		HttpServletResponse response = (HttpServletResponse) org1;
		try {
			..........
			chain.doFilter(org0, org1);//到STRUTS的FILTER
			..........
		}catch (Exception e) {//现在这里现在永远到不了
			sendEmailIfNecessary(e, request);//发邮件
		}

查了很久,发现此版本不再抛异常了,org.apache.struts2.dispatcher.Dispatcher类serviceAction方法代码
 public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
                              ActionMapping mapping) throws ServletException {

        .......;
        try {
            ......;
        } catch (ConfigurationException e) {//异常处理
        	// WW-2874 Only log error if in devMode
        	if(devMode) {
        		LOG.error("Could not find action or result", e);
        	}
        	else {
        		LOG.warn("Could not find action or result", e);
        	}
            sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
        } catch (Exception e) {
            //这里以前是throw new ServletException(e);
            sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
        } finally {
            UtilTimerStack.pop(timerKey);
        }
    }

来看看sendError的代码
 public void sendError(HttpServletRequest request, HttpServletResponse response,
            ServletContext ctx, int code, Exception e) {
        if (devMode) {
///开发模式,即Struts的配置文件中有设如下设置<constant name="struts.devMode" value="true" />
            response.setContentType("text/html");

            try {
                FreemarkerManager mgr = getContainer().getInstance(FreemarkerManager.class);

                freemarker.template.Configuration config = mgr.getConfiguration(ctx);
                Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl");

                List<Throwable> chain = new ArrayList<Throwable>();
                Throwable cur = e;
                chain.add(cur);
                while ((cur = cur.getCause()) != null) {
                    chain.add(cur);
                }

                HashMap<String,Object> data = new HashMap<String,Object>();
                data.put("exception", e);
                data.put("unknown", Location.UNKNOWN);
                data.put("chain", chain);
                data.put("locator", new Locator());
                template.process(data, response.getWriter());
                response.getWriter().close();
            } catch (Exception exp) {
                try {
                    response.sendError(code, "Unable to show problem report: " + exp);
                } catch (IOException ex) {
                    // we're already sending an error, not much else we can do if more stuff breaks
                }
            }
        } else {//普通模式
            try {
                // WW-1977: Only put errors in the request when code is a 500 error
                if (code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
                    // send a http error response to use the servlet defined error handler
                    // 原来异常被这样处理掉了
                    request.setAttribute("javax.servlet.error.exception", e);

                    // for compatibility
                    request.setAttribute("javax.servlet.jsp.jspException", e);
                }

                // send the error response
                response.sendError(code, e.getMessage());
            } catch (IOException e1) {
                // we're already sending an error, not much else we can do if more stuff breaks
            }
        }
    }

再把结果说明白一点,
1、开发模式:异常不好拿了,异常信息被直接写到页面,不过没关系,开发嘛,这不正是你想要的吗
2、正常模式:通过request.getAttribute("javax.servlet.error.exception")或者request.getAttribute("javax.servlet.jsp.jspException")可以取得异常对象。
   //刷屏,远离广告

你可能感兴趣的:(apache,jsp,freemarker,struts,servlet)