使用Trinidad导出CSV/PDF文件时,会遇到getOutputStream() has already been called的异常,其原因是JSF在导出文件的时候会调用response.getWriter()方法,而在此之前backingbean中调用了response.getOutputStream()方法。两者会有冲突。看一下org.apache.catalina.connector.Response.java的源代码就知道,如果调用了getOutputStream() 方法,则usingOutputStream=true,再调用getWriter()方法就会抛异常,代码片断如下:
609 if (usingOutputStream)
610 throw new IllegalStateException
611 (sm.getString("coyoteResponse.getWriter.ise"));
出现这种异常的场景如下:
使用Trinidad中的控件导出CSV文件
==========.xhtml=======================================
...
<tr:commandButton icon="../images/csv.jpg" shortDesc="Export to CSV">
<tr:fileDownloadActionListener
contentType="text/csv; charset=utf-8" filename="content.csv"
method="#{backingBean.exportCsv}" />
</tr:commandButton>
...
==========================
=========backingBean===================================
public final void sendContent(final FacesContext context,
final OutputStream out,
final UIXTable table)
throws IOException {
OutputStreamWriter outw = new OutputStreamWriter(out, "UTF-8");
Object rowKey = table.getRowKey();
for (int i = 0; i < table.getRowCount(); i++) {
table.setRowIndex(i);
if (!table.isRowAvailable()) {
break;
}
exportRow(table, outw);
}
outw.flush();
table.setRowKey(rowKey);
}
====================================
after exporting csv file, there is an error on console like this:
=============================================================
SEVERE: Servlet.service() for servlet Spring Dispatcher Servlet threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:610)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
at com.sun.facelets.FaceletViewHandler.createResponseWriter(FaceletViewHandler.java:400)
at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:557)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:189)
at org.apache.myfaces.trinidadinternal.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:176)
at org.springframework.faces.webflow.JsfView.render(JsfView.java:94)
at org.springframework.webflow.engine.ViewState.render(ViewState.java:245)
at org.springframework.webflow.engine.ViewState.resume(ViewState.java:204)
at org.springframework.webflow.engine.Flow.resume(Flow.java:545)
at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:262)
at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:163)
at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:173)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
......
在导出CSV的时候,可以用一个替代方案,就是用Writer代替OuputStream,这样就不会有异常了。
但如果我们使用iText导出PDF文件,就必须使用OutputStream,所以也会有上述异常出现。
对于这种情况有一个折中的解决方案, that is, call servlet in webflow, then export pdf in servlet.
the sevlet is independant on Webflow and JSF, so the getWriter() mothod won't be called by the container.
the solution is like below
========================================
listView.xhtml
========================================
<tr:commandLink action="exportPdf">
<tr:image source="../images/pdf.jpg" shortDesc="Export to PDF"/>
</tr:commandLink>
===============================================
webflow.xml
===============================================
<view-state id="listView">
...
<transition on="exportPdf" to="pdfView" >
<evaluate expression="backingBean.saveTable()" />
</transition>
</view-state>
...
<view-state id="pdfView" view="externalRedirect:contextRelative:/exportPdfAction" >
<transition to="txnHistoryListView" />
</view-state>
================================================
in the saveTable() method of backingbean, we can put tabel value and related value into HTTPSession like this.
===========================================
backingbean.java
===========================================
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
attributes.setAttribute("key", tableValue, RequestAttributes.SCOPE_SESSION);
=================================================
"externalRedirect:contextRelative:/exportPdfAction" configured in webflow.xml will navigator to
the servlet configured in web.xml
in servlet, we can get data from session and invoke method to export pdf file.
you should pay attention to one thing, that is, you can't pass UIXTable object into the session.
Because out of JSF lifecycle, we can't get label value from the UIXTable object.
I guess this is related to the FacesContext issue.
so you should wrap the data in UIXTable into your own object and save it into session.
原帖地址:
http://jsfgroup.group.iteye.com/group/topic/9959?page=2
分享到:
相关推荐
Apache MyFaces Trinidad 2.0.0-beta-2 是一个基于JavaServer Faces (JSF) 2.0标准的开源Web开发框架。这个版本的Trinidad致力于为开发者提供丰富的用户界面组件,帮助他们构建功能强大的企业级Web应用程序。...
《MyFaces Trinidad高级实用指南》是一本面向Java开发者的实用指南,尤其适合那些对JSF(JavaServer Faces)技术感兴趣的初学者和有经验的Web开发人员。本书深入探讨了Apache MyFaces Trinidad的使用,重点是代码...
在`jsfApi`这个压缩包文件中,可能包含了JSF API的JAR文件,这些文件是开发基于MyFaces Core 1.2.0的JSF应用所必需的依赖库。开发人员可以将这些JAR添加到项目的类路径中,以便利用JSF API提供的功能来构建和运行Web...
文件上传功能是MyFaces Trinidad提供的另一项功能,它允许用户在JSF应用中上传文件,而不需要额外的插件或工具。 在使用表格方面,MyFaces Trinidad提供了强大的表格组件,允许开发人员以各种方式展示数据,并允许...
Apache MyFaces Trinidad是一款开源的JavaServer Faces (JSF)组件库,主要由Apache软件基金会开发。这个库提供了丰富的用户界面组件,旨在简化Web应用程序的开发。Maven是Java项目管理工具,它通过定义项目的构建...
MyFaces JSF Tobago 全部 JAR 包是一组重要的软件组件,它们构成了一个功能丰富的用户界面(UI)框架,适用于JavaServer Faces (JSF)应用程序开发。这个压缩包包含了一系列的JAR文件,这些文件是MyFaces Tobago项目...
Trinidad是Oracle公司开发的一款用于构建JavaServer Faces (JSF) 应用的开源UI组件库。这个库提供了丰富的用户界面组件,使得开发者可以更轻松地创建功能强大的企业级Web应用程序。Trinidad,又称为MyFaces Trinidad...
11. **部署和配置**:在实际项目中,需要了解如何在Web应用的部署描述符(web.xml)中配置Trinidad,以及如何在 faces-config.xml 文件中定义组件和行为。 通过学习和掌握Apache MyFaces Trinidad,开发者可以利用其...
"Trinidad-1.0.jar" 是一个专为JavaServer Faces (JSF)框架提供增强功能的扩展库。JSF是一种用于构建企业级Web应用程序的Java标准,它提供了丰富的组件库和模型-视图-控制器(MVC)架构。Trinidad是Oracle公司开发的...
- **组件**:JSF中的核心概念之一是组件。组件是构成页面的基本单位,可以是按钮、文本框或其他UI元素。组件可以被嵌套在其他组件中,形成复杂的布局结构。 - **事件处理**:JSF组件支持事件处理机制,允许开发者...
官方版本,亲测可用
【标题】"trinidad-bolivia.zip" 是一个压缩文件,通常用于存储多个相关文件以减少传输和存储空间。在本例中,它可能包含了与特立尼达和多巴哥以及玻利维亚这两个国家相关的CAD(计算机辅助设计)图纸。 【描述】...
Packt - Apache MyFaces Trinidad 1.2, A Practical Guide (2009) Develop JSF web applications with Trinidad and Seam pdf
通过本篇文章的详细介绍,相信读者已经掌握了ADF中文件上传的基本实现方法,包括页面代码的编写、管理Bean的处理逻辑以及如何根据需要调整文件上传大小限制。这些知识将有助于开发者在实际项目中更加高效地实现文件...
9. **兼容性和互操作性**:MyFaces Orchestra Framework 1.4 应该与标准的JSF 1.2 兼容,并且可以与其他MyFaces组件库无缝集成,如Tomahawk、Trinidad等。 10. **文档和社区支持**:作为Apache项目的一部分,...
6. **部署和使用**: 要在项目中使用MyFaces,你需要将这些JAR文件添加到你的类路径中,并在web.xml配置文件中指定MyFaces作为JSF实现。如果你使用的是Maven或其他依赖管理工具,可以通过指定相应的依赖来简化这个...
Beezer is a Professor of Mathematics at the University of Puget Sound, where he has been on the faculty since 1984. He received a B.S. in Mathematics (with an Emphasis in Computer Science) from the ...