HTTP response header content disposition for attachments

135,992

Solution 1

Problems

The code has the following issues:

  • An Ajax call (<a4j:commandButton .../>) does not work with attachments.
  • Creating the output content must happen first.
  • Displaying the error messages also cannot use Ajax-based a4j tags.

Solution

  1. Change <a4j:commandButton .../> to <h:commandButton .../>.
  2. Update the source code:
    1. Change bw.write( getDomainDocument() ); to bw.write( document );.
    2. Add String document = getDomainDocument(); to the first line of the try/catch.
  3. Change the <a4j:outputPanel.../> (not shown) to <h:messages showDetail="false"/>.

Essentially, remove all the Ajax facilities related to the commandButton. It is still possible to display error messages and leverage the RichFaces UI style.

References

Solution 2

neither use inline; nor attachment; just use

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

or

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

or

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

Solution 3

Try changing your Content Type (media type) to application/x-download and your Content-Disposition to: attachment;filename=" + fileName;

response.setContentType("application/x-download");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
Share:
135,992
Dave Jarvis
Author by

Dave Jarvis

https://dave.autonoma.ca/blog/

Updated on March 31, 2020

Comments

  • Dave Jarvis
    Dave Jarvis about 4 years

    Background

    Write an XML document to a browser's response stream and cause the browser to display a "Save As" dialog.

    Problem

    Consider the following download() method:

      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();
    

    In Firefox, the XML content is displayed in the browser window. In IE 7, the XML content is not displayed -- you have to view the document source. Neither situation is the desired result.

    The web page uses the following code for the button:

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

    The XML that is generated does not start with <?xml version="1.0"?>, rather the XML content resembles:

    <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>
    

    Update #1

    Note the following line of code:

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

    Update #2

    Using <a4j:commandButton ... /> is the problem; a regular <h:commandButton .../> performs as expected. Using the <h:commandBUtton .../> prevents the <a4j:outputPanel .../> from refreshing any error messages.

    Related Seam Message.

    Mime Type

    The following mime types do not trigger the "Save As" dialog:

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

    Question

    What changes will cause the a4j:commandButton to trigger a "Save As" dialog box so that the user is prompted to save the XML file (as domain.xml)?

    Thank you.

  • eeq
    eeq about 13 years
    Sounds like this is an Eclipse issue then. Using the embedded browser? Maybe it has some configuration that disables download popups or something.
  • Sergey Ushakov
    Sergey Ushakov about 9 years
    All this looks very concise and reasonable, but why avoid "attachment"? Though RFC 6266 suggests that 'unknown or unhandled disposition types SHOULD be handled by recipients the same way as "attachment"', 'SHOULD' is not the same as 'MUST'. 'attachment' just makes this technique more reliable...
  • Zesky
    Zesky over 8 years
    Internet explorer 11 will try to load the document (e.g. doc) in new tab with weird string if you miss out "attachment" in content disposition