如何在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解决此问题。

如果您不想记录任何SocketExceptionexception堆栈跟踪,那么只需在登录到文件时跳过它。

要遵循的步骤:

  • 自定义处理程序必须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 loggers Jboss-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写入日志文件。 为此,您需要提供日志文件路径