如何在Console上停止打印exception堆栈跟踪?
我编写了一个servlet来处理我的Web应用程序中发生的exception并将它们映射到web.xml中
java.lang.Exception /exceptionHandler
这是我在exception处理servlet service
方法中所做的:
@Override protected void service(HttpServletRequest req, HttpServletResponse arg1) throws ServletException, IOException { Object attribute = req.getAttribute("javax.servlet.error.exception"); if(attribute instanceof SocketException){ // don't do anything }else{ super.service(req, arg1); } }.
问题:
上述方法无效,堆栈跟踪正在打印到控制台。 当用户请求某些内容然后关闭其浏览器时会发生这种情况。
题:
每当发生SocketException
时,如何停止将printtrace打印到JBoss控制台?
这样做的原因:
我想避免在第一天结束时看到所有日志的SocketException
,因为我无法对这些信息做任何事情。
这就是我在战争中所做的工作。
添加了一个filter并劫持了所有请求和响应。捕获exception并检查类型。
/** * Hijacks all the http request and response here. * Catch the SocketException and do not print * If other exceptions print to console * date : 9-18-2013 * * @author Suresh Atta * */ public class ExceptionHandler implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { try{ arg2.doFilter(arg0, arg1); }catch(SocketException e ){ // Please don't print this to log. } } }
在web.xml
,过滤映射
ExceptionHandler com.nextenders.server.ExceptionHandler ExceptionHandler REQUEST /*
我不是把它标记为答案,因为我不确定这是否是标准方法。只是一个解决方法。
不要在web.xml中添加java.lang.Exception
,为什么不尝试在web.xml本身中添加套接字exception,如下所示
java.net.SocketException /exceptionHandler
并且只是在你的servlet中什么都不做或者改为添加一个空的jsp文件
java.net.SocketException /error.jsp
使用Jboss Custom Logging Handler解决此问题。
如果您不想记录任何SocketException
exception堆栈跟踪,那么只需在登录到文件时跳过它。
要遵循的步骤:
- 自定义处理程序必须inheritancejava.util.logging.Handler
这是代码:
package com.custom.jboss.logging; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import java.util.logging.ErrorManager; import java.util.logging.Handler; import java.util.logging.LogRecord; public class SocketExceptionCustomLoggingHandler extends Handler { private String logFile; public BufferedWriter out = null; public SocketExceptionCustomLoggingHandler() { super(); logFile = ""; } @Override public void publish(LogRecord record) { if (!initialize()) { return; } if (isLoggable(record)) { process(record); } } private synchronized boolean initialize() { if (out == null && logFile != null && !logFile.equals("")) { FileWriter fstream = null; try { fstream = new FileWriter(logFile, true); out = new BufferedWriter(fstream); } catch (IOException e) { reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE); } logToFile("Log file initialized. Logging to: " + logFile); } return true; } private void process(LogRecord logRecord) { String log = getFormatter().format(logRecord); if (log.indexOf("java.net.SocketException") == -1) { logToFile(log); } } private void logToFile(String text) { try { if (out != null) { out.write((new Date()).toString() + "\t" + text + "\n"); out.flush(); } } catch (IOException e) { reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE); } } @Override public void flush() { try { if (out != null) { out.flush(); } } catch (IOException e) { reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE); } } @Override public void close() { if (out != null) { try { out.close(); } catch (IOException e) { reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE); } } } public void setLogFile(String logFile) { this.logFile = logFile; } }
-
然后将该文件打包到jar中并放在modules目录中。
即
Jboss-7.1.1/modules/com/custom/jboss/loggers/main
loggersJboss-7.1.1/modules/com/custom/jboss/loggers/main
以及module.xml文件。 module.xml的内容应如下所示。 -
然后修改standalone.xml以支持记录到自定义记录器
... -
如果需要,在root-logger中添加更多处理程序,如FILE,CONSOLE等。
- 现在,所有日志都将通过此自定义处理程序记录在您的自定义日志文件中,我们已跳过
SocketException
- 我们可以使这个类更通用,从standalone.xml传递属性,例如用于传递日志文件路径。
如果有任何问题,请告诉我。
您可能必须覆盖fillInStackTrade方法
public static class CustomException extends Exception { @Override public Throwable fillInStackTrace() { return null; }
}
据我了解,当到达容器之前没有捕获exception时,会将exception记录到控制台。 因此,使用filter来捕获未处理的exception是有道理的。
默认情况下,Struts2还有一个exception“拦截器”作为它的最后一个拦截器。 请参见defaultStack 。 如果我们需要自定义exception处理,我们需要覆盖此拦截器。
我唯一要做的就是记录exception(至少是一个errors-ignore.txt文件),而不是完全跳过它们。
另一个时髦的想法:你可以创建exception处理程序
class SocketExceptionSwallower implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { if (e instanceof SocketException) { // swallow } else { e.printStackTrace(); } } }
并注册
Thread.setDefaultUncaughtExceptionHandler(new SocketExceptionSwallower());
要么
Thread.currentThread().setUncaughtExceptionHandler(new SocketExceptionSwallower());
简单,没有链中的另一个filter的开销,但它与线程混淆,可能会破坏Java EE环境中的某些东西)
可能在测试/试验中有用,或者如果您在自己的代码中完全控制线程
您可以使用Logger
。 为此,您需要log4j
库,并将所有需要的行为和exception写入日志文件。 为此,您需要提供日志文件路径