我正在使用jetty-9.0.5.v20130815,Struts 2.3.15.1,当我尝试使用Chrome和Chrome浏览器下载文件时,会出现以下错误:
ERROR 17/09/2013 10:26:11
(br.com.arquimagem.support.web.struts2.interceptor.ExceptionHandlerInterceptor):Unexpected error on action: class br.com.arquimagem.support.web.action.CommonFilesAction
org.eclipse.jetty.io.EofException
at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:186)
at org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:400)
at org.eclipse.jetty.io.SelectChannelEndPoint.onSelected(SelectChannelEndPoint.java:111)
at org.eclipse.jetty.io.SelectorManager$ManagedSelector.processKey(SelectorManager.java:498)
at org.eclipse.jetty.io.SelectorManager$ManagedSelector.select(SelectorManager.java:455)
at org.eclipse.jetty.io.SelectorManager$ManagedSelector.run(SelectorManager.java:420)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.io.IOException: An established connection was aborted by the software in your host machine
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)
at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:165)
... 8 more
2013-09-17 10:26:11.441:WARN:oejs.Response:qtp776813247-5034: Committed before 500 STREAM
2013-09-17 10:26:11.456:WARN:oejs.ServletHandler:qtp776813247-5034: /GedocLog/CommonFile
java.lang.IllegalStateException: Committed
at org.eclipse.jetty.server.Response.resetBuffer(Response.java:999)
at org.eclipse.jetty.server.Response.sendError(Response.java:351)
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:906)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:586)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1486)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:138)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:564)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:213)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1096)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:432)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1030)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:201)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:445)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:268)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:229)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532)
at java.lang.Thread.run(Thread.java:724)
我的struts.xml:
<package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="customException" class="br.com.arquimagem.support.web.struts2.interceptor.ExceptionHandlerInterceptor"> <param name="result">globalError</param> </interceptor> <interceptor name="customFileUpload" class="br.com.arquimagem.support.web.struts2.interceptor.CustomFileUploadInterceptor"> <param name="result">globalError</param> </interceptor> <!-- Default Stack --> <interceptor-stack name="defaultStack"> <interceptor-ref name="customException" /> <!-- <interceptor-ref name="customFileUpload" /--> <!-- <interceptor-ref name="alias" /--> <!-- <interceptor-ref name="prepare" /--> <!-- <interceptor-ref name="i18n" /--> <!-- <interceptor-ref name="chain" /--> <interceptor-ref name="params" /> <!-- <interceptor-ref name="conversionError" /--> <interceptor-ref name="validation" /> <!-- <interceptor-ref name="workflow"<param name="inputResultName">generalError</param </interceptor-ref--> </interceptor-stack> <!-- Upload Stack --> <interceptor-stack name="uploadStack"> <interceptor-ref name="customException" /> <interceptor-ref name="customFileUpload" /> <interceptor-ref name="params" /> <interceptor-ref name="validation" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack" /> <default-action-ref name="index" /> <global-results> <result name="globalError">/pages/error/general.jsp </result> <result name="generalError">/pages/error/general.jsp </result> </global-results> <action name="CommonFile" class="br.com.arquimagem.support.web.action.CommonFilesAction"> <result name="sendFile" type="stream"> <param name="bufferSize">1024</param> <param name="allowCaching">false</param> </result> <result>/pages/resultCommand.jsp</result> </action> </package> </struts>
为什么这种情况只发生在Chrome中并且大约一个月?
自定义拦截器:
package br.com.arquimagem.support.web.struts2.interceptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import org.apache.log4j.Logger;
import br.com.arquimagem.support.exception.InfraStructureException;
import br.com.arquimagem.support.exception.InvalidParameterException;
import br.com.arquimagem.support.log4j.InfraStructureLoggerFactory;
import br.com.arquimagem.support.web.action.AbstractBaseAction;
import br.com.arquimagem.support.web.util.MessageConstants;
import br.com.arquimagem.support.web.util.Struts2Utils;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.ExceptionHolder;
import com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor;
public class ExceptionHandlerInterceptor extends ExceptionMappingInterceptor
{
private static final long serialVersionUID = -2677219300348931782L;
private String result = AbstractBaseAction.ERROR;
protected static Logger logger = InfraStructureLoggerFactory
.getLogger(ExceptionHandlerInterceptor.class);
@Override
public String intercept(ActionInvocation invocation) throws Exception {
try {
return super.intercept(invocation);
}
catch (InvocationTargetException e) {
if (e.getTargetException() instanceof OutOfMemoryError) {
publishOutOfMemoryException(invocation, new ExceptionHolder(e));
}
else {
publishException(invocation, new ExceptionHolder(e));
throw e;
}
}
catch (InvalidParameterException ipe) {
publishInvalidParameterException(invocation, new ExceptionHolder(ipe));
}
catch (InfraStructureException ise) {
publishInfraException(invocation, new ExceptionHolder(ise));
}
catch (Exception ex) {
publishException(invocation, new ExceptionHolder(ex));
}
return result;
}
protected void publishAuthorizationException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
super.publishException(invocation, exceptionHolder);
logger.error("AuthorizationException exception on action: " + invocation.getAction().getClass().toString(),
exceptionHolder.getException());
setErrorMessage(MessageConstants.COMMON_0003, invocation);
}
protected void publishInvalidParameterException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
super.publishException(invocation, exceptionHolder);
logger.error("InvalidParameter exception on action: " + invocation.getAction().getClass().toString(),
exceptionHolder.getException());
setErrorMessage(MessageConstants.COMMON_0005, invocation);
}
protected void publishInfraException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
super.publishException(invocation, exceptionHolder);
logger.error("Infra structure exception on action: " + invocation.getAction().getClass().toString(),
exceptionHolder.getException());
setErrorMessage(MessageConstants.COMMON_0004, invocation);
}
@Override
protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
super.publishException(invocation, exceptionHolder);
logger.error("Unexpected error on action: " + invocation.getAction().getClass().toString(),
exceptionHolder.getException());
setErrorMessage(MessageConstants.COMMON_0006, invocation);
}
protected void publishOutOfMemoryException(ActionInvocation invocation, ExceptionHolder exceptionHolder) {
super.publishException(invocation, exceptionHolder);
logger.error("OutOfMemory Exception: " + invocation.getAction().getClass().toString(),
exceptionHolder.getException());
setErrorMessage(MessageConstants.COMMON_0014, invocation);
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
private void setErrorMessage(String key, ActionInvocation invocation) {
try {
((AbstractBaseAction) invocation.getAction()).addError(key, Collections.emptyList());
}
catch (Exception e) {
((ActionSupport) invocation.getAction()).addActionError(Struts2Utils.getTextFromInvocation(invocation, key,
Collections.EMPTY_LIST));
}
}
}
我的CustomFileUploadInterceptor只是扩展FileUploadInterceptor。