首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用带有自定义HTTP头的托管Bean生成PDF

使用带有自定义HTTP头的托管Bean生成PDF
EN

Stack Overflow用户
提问于 2012-11-30 23:23:29
回答 1查看 1.5K关注 0票数 0

背景

使用ADF任务流生成各种格式的报表(例如PDF、分隔的HTML)。

问题

HTTP头被发送了两次:一次是由框架发送的,一次是由bean发送的。

源代码

源代码包括:

  • 按钮动作
  • 管理豆
  • 任务流程

按钮动作

按钮动作:

代码语言:javascript
复制
<af:commandButton text="Report" id="submitReport" action="Execute" />

管理豆

托管Bean相当复杂。responseComplete的代码正在被调用,但是它似乎没有被足够早地调用,从而阻止应用程序框架编写headers。

HTTP响应头覆盖

代码语言:javascript
复制
/**
 * Sets the HTTP headers required to indicate to the browser that the
 * report is to be downloaded (rather than displayed in the current
 * window).
 */
protected void setDownloadHeaders() {
  HttpServletResponse response = getServletResponse();
  response.setHeader( "Content-Description", getContentDescription() );
  response.setHeader( "Content-Disposition", "attachment, filename="
    + getFilename() );
  response.setHeader( "Content-Type", getContentType() );
  response.setHeader( "Content-Transfer-Encoding",
    getContentTransferEncoding() );
}

问题响应完成

代码语言:javascript
复制
getFacesContext().responseComplete();

Bean运行和配置

代码语言:javascript
复制
public void run() {
  try {
    Report report = getReport();
    configure(report.getParameters());
    report.run();
  } catch (Exception e) {
    e.printStackTrace();
  }
}

private void configure(Parameters p) {
  p.put(ReportImpl.SYSTEM_REPORT_PROTOCOL, "http");
  p.put(ReportImpl.SYSTEM_REPORT_HOST, "localhost");
  p.put(ReportImpl.SYSTEM_REPORT_PORT, "7002");
  p.put(ReportImpl.SYSTEM_REPORT_PATH, "/reports/rwservlet");
  p.put(Parameters.PARAM_REPORT_FORMAT, "pdf");

  p.put("report_cmdkey", getReportName());
  p.put("report_ORACLE_1", getReportDestinationType());
  p.put("report_ORACLE_2", getReportDestinationFormat());
}

任务流程

任务流调用Execute,它引用bean的run()方法:

代码语言:javascript
复制
entry -> main -> Execute -> ReportBeanRun

其中:

代码语言:javascript
复制
  <method-call id="ReportBeanRun">
    <description>Executes a report</description>
    <display-name>Execute Report</display-name>
    <method>#{reportBean.run}</method>
    <outcome>
      <fixed-outcome>success</fixed-outcome>
    </outcome>
  </method-call>

bean被分配给request作用域,并有一些托管属性:

代码语言:javascript
复制
  <control-flow-rule id="__3">
    <from-activity-id>main</from-activity-id>
    <control-flow-case id="ExecuteReport">
      <from-outcome>Execute</from-outcome>
      <to-activity-id>ReportBeanRun</to-activity-id>
    </control-flow-case>
  </control-flow-rule>

  <managed-bean id="ReportBean">
    <description>Executes a report</description>
    <display-name>ReportBean</display-name>
    <managed-bean-scope>request</managed-bean-scope>
    ...
  </managed-bean>

<fixed-outcome>success</fixed-outcome>给我的印象是不正确的--我不希望方法调用返回到另一个任务。

限制

报表服务器只接收来自web服务器的请求。出于安全原因,浏览器不能直接下载报表服务器URL。

错误信息

生成的错误消息:

从服务器接收的重复标头 错误349 (net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION):多个不同的内容处理头接收。这是不允许的,以防止HTTP响应分裂攻击。

然而,该报告正在编写之中。阻止框架写入HTTP头将解决此问题。

问题

如何在使用任务流通过调用托管bean生成PDF时,在ADF中设置HTTP头?

想法

其他一些想法:

  • 重写页面生命周期阶段侦听器(ADFPhaseListener + PageLifecycle)
  • 在web服务器上开发自定义Servlet

相关链接

  • http://www.oracle.com/technetwork/middleware/bi-publisher/adf-bip-ucm-integration-179699.pdf
  • http://www.slideshare.net/lucbors/reports-no-notes#btnNext
  • 102062735
  • lifecycle.htm#CIABEJFB

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-03 21:45:07

问题是不正确地执行RFC 2183:

代码语言:javascript
复制
response.setHeader( "Content-Disposition", "attachment; filename="
  + getFilename() );

;不能是,

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13654625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档