我编写了一个servlet来处理我的Web应用程序中发生的异常并将它们映射到web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/exceptionHandler</location>
</error-page>
以下是我在异常处理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
,因为我无法对该信息做任何事情。
答案 0 :(得分:7)
这就是我在战争中所做的工作。
添加了一个过滤器并劫持了所有请求和响应。捕获异常并检查类型。
/**
* 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
中,过滤映射
<filter>
<filter-name>ExceptionHandler</filter-name>
<filter-class>com.nextenders.server.ExceptionHandler</filter-class>
</filter>
<filter-mapping>
<filter-name>ExceptionHandler</filter-name>
<dispatcher> REQUEST </dispatcher>
<url-pattern> /*</url-pattern>
</filter-mapping>
我不是将此标记为答案,因为我不确定这是否是标准方法。只是一个解决方法。
答案 1 :(得分:7)
不是在web.xml中添加java.lang.Exception
,为什么不尝试在web.xml本身添加套接字异常,如下所示
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/exceptionHandler</location>
</error-page>
并且在servlet中什么也不做
或而是添加一个空的jsp文件,如
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/error.jsp</location>
</error-page>
答案 2 :(得分:3)
使用 Jboss自定义日志记录处理程序来解决此问题。
如果您不想记录任何SocketException
异常堆栈跟踪,那么只需在登录文件时跳过它。
要遵循的步骤:
以下是代码:
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
和module.xml文件一起使用。 module.xml的内容应如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="com.custom.jboss.loggers">
<resources>
<resource-root path="SocketExceptionHandler.jar"/>
<!-- Insert resources here -->
</resources>
<dependencies>
<module name="org.jboss.logging"/>
<module name="javax.api"/>
</dependencies>
</module>
然后修改standalone.xml以支持记录到自定义记录器
<subsystem xmlns="urn:jboss:domain:logging:1.1">
...
<custom-handler name="SocketExceptionAppender" class="com.custom.jboss.logging.SocketExceptionCustomLoggingHandler" module="com.custom.jboss.loggers">
<level name="DEBUG"/>
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<properties>
<property name="logFile" value="d:\\temp\\logfile.txt"/>
</properties>
</custom-handler>
...
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="SocketExceptionAppender"/>
</handlers>
</root-logger>
</subsystem>
如果需要,可以在root-logger中添加更多处理程序,例如FILE,CONSOLE等。
SocketException
如果有任何问题,请告诉我。
答案 3 :(得分:2)
您可能必须覆盖fillInStackTrade方法
public static class CustomException extends Exception {
@Override
public Throwable fillInStackTrace() {
return null;
}
}
答案 4 :(得分:2)
根据我的理解,在到达容器之前未捕获异常时会将异常记录到控制台。因此,使用过滤器来捕获未处理的异常是有道理的。
默认情况下,Struts2还有一个异常“拦截器”作为它的最后一个拦截器。见defaultStack。如果我们需要自定义异常处理,我们需要覆盖这个拦截器。
我唯一要做的就是记录异常(至少是一个errors-ignore.txt文件),而不是完全跳过它们。
答案 5 :(得分:1)
另一个时髦的想法:你可以创建异常处理程序
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());
简单,没有链中的另一个过滤器的开销,但是它与线程混淆并且可能在Java EE环境中破坏某些东西)
可能在测试/实验中有用,或者如果您完全控制自己代码中的线程
答案 6 :(得分:1)
您可以使用Logger
。为此,您需要log4j
库,并将所有所需的行为和异常写入日志文件。为此,您需要提供日志文件路径