我在 websphere 8.5.0.1 上使用jsf 2( javax.faces-2.0.10.jar )和 primefaces 3.5 我也在使用文件上传jar:
我正在尝试使用primefaces fileupload组件,如下所示:
<h:form id="frm" enctype="multipart/form-data">
<p:fileUpload id="fileUpload" value="#{uploadDocument.file}"
fileUploadListener="#{uploadDocument.handleFileUpload}" mode="advanced" dragDropSupport="false"
sizeLimit="10000000" fileLimit="3" />
</h:form>
web.xml配置:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>uploadDirectory</param-name>
<param-value>C:/uploadFolder</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
选择文件并单击上传后,文件未上传,我在日志文件中收到以下警告:
com.ibm.ws.webcontainer.srt.SRTServletResponse addHeader SRVE8094W: WARNING: Cannot set header. Response already committed.
请告知文件上传无效的原因?
答案 0 :(得分:0)
显然,您的响应已在抛出异常的行之前提交。我还没有看到你在那里找到的具体例子,但问题很常见,并且有一种通用的方法可以跟踪这些问题。在您预期之前会有一些内容写入您的响应,但您看到的堆栈跟踪是针对稍后尝试添加到该响应的事件。因此,解决方案是在提交响应时记录堆栈跟踪 ,然后在抛出异常的稍后时刻,打印第一个堆栈跟踪。
我没有像以前那样用来执行此操作的代码,正如我为之前的公司所写的那样。我在下面提出了一个大纲解决方案,它显示了它的要点 - 你需要包装响应,以及它返回的任何servletoutputstream / printwriter对象来检测commit事件。我已经展示了如何通过使用内省来完成这项工作;但如果您愿意,可以为流/写入器使用ServletResponseWrapper和自定义包装器类。事实上,你不需要像我一样包装尽可能多的方法。
在我们的真实&#39;代码,我记录了堆栈跟踪并仅在问题发生时打印出来,如上所述,但下面的代码只是在提交响应时记录,你可以通过查看你的日志找出哪一个。
public class BadCommitFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletRequest) res;
response=Proxy.newProxyInstance(this.getClass().getClassLoader(),
new Class[] { HttpServletResponse.class },
new ResponseInvocationHandler(response, response));
chain.doFilter(req, response);
}
private static class ResponseInvocationHandler<T> implements InvocationHandler {
final T proxied;
final HttpServletResponse response;
public ResponseInvocationHandler(T proxied, HttpServletResponse response) {
this.proxied = proxied;
this.response = response;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// in the 'real' code, I checked against a threadlocal
// at the end only, so there was no possibility that I'd
// miss out methods.
boolean isCommitted = res.isCommitted();
try {
Object ret = method.invoke(proxied, args);
if (ret instanceof PrintWriter) {
Proxy.newProxyInstance(ret.getClass().getClassLoader(),
new Class[] { PrintWriter.class },
new ResponseInvocationHandler(ret, response));
} else if (ret instanceof ServletOutputStream) {
Proxy.newProxyInstance(ret.getClass().getClassLoader(),
new Class[] { ServletOutputStream.class },
new ResponseInvocationHandler(ret, response));
}
} finally {
if(!isCommitted && res.isCommitted()) {
try { throw Exception("First Committed:"); }
// or however you want to log this
catch(Exception e){e.printStackTrace();}
}
}
return ret;
}
}
}
如果您遇到代码问题,可能会有一些常见的嫌疑人需要查找。记住承诺可以被明确触发,但更多时候是因为你已经将足够的数据写入缓冲区,它必须刷新:
<%@ page contentType="text/html; charset=UTF-8"%>
之类但后转到另一个servlet的jsps是错误的。 答案 1 :(得分:0)
问题是因为当我删除它时,我的类路径上有一个名为appbase.jar
的jar,一切正常。