附件的HTTP响应标头内容处置

时间:2011-03-11 22:16:12

标签: java ajax jboss richfaces attachment

背景

将XML文档写入浏览器的响应流,并使浏览器显示“另存为”对话框。

问题

考虑以下download()方法:

  HttpServletResponse response = getResponse();

  BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(
      response.getOutputStream() ) );

  String filename = "domain.xml";
  String mimeType = new MimetypesFileTypeMap().getContentType( filename );

  // Prints "application/octet-stream"
  System.out.println( "mimeType: " + mimeType );

  // response.setContentType( "text/xml;charset=UTF-8" );
  response.setContentType( mimeType );
  response.setHeader( "Content-Disposition", "attachment;filename="
      + filename );

  bw.write( getDomainDocument() );
  bw.flush();
  bw.close();

在Firefox中,XML内容显示在浏览器窗口中。在IE 7中,不显示XML内容 - 您必须查看文档源。这两种情况都不是理想的结果。

网页使用以下代码作为按钮:

    <a4j:commandButton action="#{domainContent.download}" value="Create Domain" reRender="error" />

生成的XML 不以<?xml version="1.0"?>开头,而是XML内容类似于:

<schema xmlns="http://www.jaspersoft.com/2007/SL/XMLSchema" version="1.0">
  <items>
    <item description="EDT Class Code" descriptionId="" label="EDT Class Code" labelId="" resourceId="as_pay_payrolldeduction.edtclass"/>
  </items>
  <resources>
    <jdbcTable datasourceId="JNDI" id="as_pay_payrolldeduction" tableName="as_pay.payrolldeduction">
      <fieldList>
        <field id="payamount" type="java.math.BigDecimal"/>
      </fieldList>
    </jdbcTable>
  </resources>
</schema>

更新#1

请注意以下代码行:

response.setHeader( "Content-Disposition", "attachment;filename=" + filename );

更新#2

使用<a4j:commandButton ... />是问题所在;常规<h:commandButton .../>按预期执行。使用<h:commandBUtton .../>会阻止<a4j:outputPanel .../>刷新任何错误消息。

相关Seam Message

Mime Type

以下mime类型不会触发“另存为”对话框:

  • "application/octet-stream"
  • "text/xml"
  • "text/plain"

问题

哪些更改会导致a4j:commandButton触发“另存为”对话框,以便提示用户保存XML文件(domain.xml)?

谢谢。

5 个答案:

答案 0 :(得分:11)

既不使用内联;也不依附;只需使用

response.setContentType("text/xml");
response.setHeader( "Content-Disposition", "filename=" + filename );

response.setHeader( "Content-Disposition", "filename=\"" + filename + "\"" );

response.setHeader( "Content-Disposition", "filename=\"" + 
  filename.substring(0, filename.lastIndexOf('.')) + "\"");

答案 1 :(得分:8)

尝试将您的内容类型(媒体类型)更改为application/x-download,将内容处置更改为:attachment;filename=" + fileName;

response.setContentType("application/x-download");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);

答案 2 :(得分:7)

问题

代码存在以下问题:

  • Ajax调用(<a4j:commandButton .../>)不适用于附件。
  • 必须先创建输出内容。
  • 显示错误消息也不能使用基于Ajax的a4j标记。

解决方案

  1. <a4j:commandButton .../>更改为<h:commandButton .../>
  2. 更新源代码:
    1. bw.write( getDomainDocument() );更改为bw.write( document );
    2. String document = getDomainDocument();添加到try/catch
    3. 的第一行
  3. <a4j:outputPanel.../>(未显示)更改为<h:messages showDetail="false"/>
  4. 基本上,删除与commandButton相关的所有Ajax工具。仍然可以显示错误消息并利用RichFaces UI样式。

    参考

答案 3 :(得分:0)

尝试Content-Disposition标题

Content-Disposition: attachment; filename=<file name.ext> 

答案 4 :(得分:0)

这与MIME类型无关,但与Content-Disposition标头无关,应该是这样的:

Content-Disposition: attachment; filename=genome.jpeg;

确保它实际上已正确传递给客户端(未由服务器,代理或其他东西过滤)。您还可以尝试更改编写标题的顺序,并在获取输出流之前设置它们。