您的位置:首页 > 编程语言 > Java开发

关于在filter中捕获Struts2异常方法说明

2013-10-25 00:00 585 查看
在在filter中捕获Struts1的异常如下:
//我的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);//发邮件
}

升级到Struts2后,发现上述代码不能捕获从Struts中抛出的异常。

经查找Struts2的源码,发现如下,在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) {
//Struts1这里以前是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")可以取得异常对象。

所以在filter中捕获Struts2异常的正确写法为:

public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, resp);
Exception e=(Exception) req.getAttribute("javax.servlet.error.exception");

if(e!=null){
sendEmailIfNecessary(e, request);//发邮件
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Struts2 异常 filter