jsf 2 - How to provide a file download from a JSF backing bean? -


is there way of providing file download jsf backing bean action method? have tried lot of things. main problem cannot figure how outputstream of response in order write file content to. know how servlet, cannot invoked jsf form , requires new request.

how can outputstream of response current facescontext?

introduction

you can through externalcontext. in jsf 1.x, can raw httpservletresponse object externalcontext#getresponse(). in jsf 2.x, can use bunch of new delegate methods externalcontext#getresponseoutputstream() without need grab httpservletresponse under jsf hoods.

on response, should set content-type header client knows application associate provided file. and, should set content-length header client can calculate download progress, otherwise unknown. and, should set content-disposition header attachment if want save as dialog, otherwise client attempt display inline. write file content response output stream.

most important part call facescontext#responsecomplete() inform jsf should not perform navigation , rendering after you've written file response, otherwise end of response polluted html content of page, or in older jsf versions, illegalstateexception message getoutputstream() has been called response when jsf implementation calls getwriter() render html.

generic jsf 2.x example

public void download() throws ioexception {     facescontext fc = facescontext.getcurrentinstance();     externalcontext ec = fc.getexternalcontext();      ec.responsereset(); // jsf component library or filter might have set headers in buffer beforehand. want rid of them, else may collide.     ec.setresponsecontenttype(contenttype); // check http://www.iana.org/assignments/media-types types. use if necessary externalcontext#getmimetype() auto-detection based on filename.     ec.setresponsecontentlength(contentlength); // set file size. header optional. work if it's omitted, download progress unknown.     ec.setresponseheader("content-disposition", "attachment; filename=\"" + filename + "\""); // save popup magic done here. can give file name want, won't work in msie, use current request url file name instead.      outputstream output = ec.getresponseoutputstream();     // can write inputstream of file above outputstream usual way.     // ...      fc.responsecomplete(); // important! otherwise jsf attempt render response fail since it's written file , closed. } 

generic jsf 1.x example

public void download() throws ioexception {     facescontext fc = facescontext.getcurrentinstance();     httpservletresponse response = (httpservletresponse) fc.getexternalcontext().getresponse();      response.reset(); // jsf component library or filter might have set headers in buffer beforehand. want rid of them, else may collide.     response.setcontenttype(contenttype); // check http://www.iana.org/assignments/media-types types. use if necessary servletcontext#getmimetype() auto-detection based on filename.     response.setcontentlength(contentlength); // set file size. header optional. work if it's omitted, download progress unknown.     response.setheader("content-disposition", "attachment; filename=\"" + filename + "\""); // save popup magic done here. can give file name want, won't work in msie, use current request url file name instead.      outputstream output = response.getoutputstream();     // can write inputstream of file above outputstream usual way.     // ...      fc.responsecomplete(); // important! otherwise jsf attempt render response fail since it's written file , closed. } 

common static file example

in case need stream static file local disk file system, substitute code below:

file file = new file("/path/to/file.ext"); string filename = file.getname(); string contenttype = ec.getmimetype(filename); // jsf 1.x: ((servletcontext) ec.getcontext()).getmimetype(filename); int contentlength = (int) file.length();  // ...  files.copy(file.topath(), output); 

common dynamic file example

in case need stream dynamically generated file, such pdf or xls, provide output there api being used expects outputstream.

e.g. itext pdf:

string filename = "dynamic.pdf"; string contenttype = "application/pdf";  // ...  document document = new document(); pdfwriter writer = pdfwriter.getinstance(document, output); document.open(); // build pdf content here. document.close(); 

e.g. apache poi hssf:

string filename = "dynamic.xls"; string contenttype = "application/vnd.ms-excel";  // ...  hssfworkbook workbook = new hssfworkbook(); // build xls content here. workbook.write(output); workbook.close(); 

note cannot set content length here. need remove line set response content length. technically no problem, disadvantage enduser presented unknown download progress. in case important, need write local (temporary) file first , provide shown in previous chapter.

turn off ajax!

you need make sure action method not called ajax request, called normal request fire <h:commandlink> , <h:commandbutton>. ajax requests handled javascript in turn has, due security reasons, no facilities force save as dialogue content of ajax response.

in case you're using e.g. primefaces <p:commandxxx>, need make sure explicitly turn off ajax via ajax="false" attribute. in case you're using icefaces, need nest <f:ajax disabled="true" /> in command component.

utility method

if you're using jsf utility library omnifaces, can use 1 of 3 convenient faces#sendfile() methods taking either file, or inputstream, or byte[], , specifying whether file should downloaded attachment (true) or inline (false).

public void download() throws ioexception {     faces.sendfile(file, true); } 

yes, code complete as-is. don't need invoke responsecomplete() , on yourself. method deals ie-specific headers , utf-8 filenames. can find source code here.


Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -