[OmniFaces utilities] The
sendFile()
sends a file to the response whose content is provided via given output stream callback. The content type will be determined based on file name. The content length will not be set because that would require buffering the entire file in memory or temp disk. The client may receive a download of an unknown length and thus the download progress may be unknown to the client. If this is undesirable, write to a temp file instead and then use Faces#sendFile(File, boolean)
. The FacesContext#responseComplete()
will implicitly be called after successful streaming.Note The caller should preferably not catch the
IOException
thrown by this method,but just re-declare it in the action method.The Servlet container will handle it.
Method
OmniFaces 2.4 | OmniFaces 2.3 |
See also: Faces#getContext() | Utils#stream() | Faces#getMimeType() | Utils#encodeURL() | Utils#encodeURI()
Usage
The relative path of the file to download is /resources/default/images/rafa.png and the user should see at download the file as rafaelnadal.png:
import org.omnifaces.util.Callback;
import
org.omnifaces.util.Callback.Output;
import
org.omnifaces.util.Faces;
...
public void downloadFile()
throws IOException {
Faces.sendFile("rafaelnadal.png",
true, new Callback.Output() {
@Override
public void writeTo(OutputStream output)
throws IOException {
FacesContext facesContext =
FacesContext.getCurrentInstance();
ExternalContext externalContext =
facesContext.getExternalContext();
Path path =
Paths.get(externalContext.getRealPath("/resources/default/images/rafa.png"));
long
contentLength = (long) Files.getAttribute(path, "basic:size",
NOFOLLOW_LINKS);
if
(contentLength != -1) {
externalContext.setResponseHeader("Content-Length",
String.valueOf(contentLength));
}
long
size = 0;
try
(ReadableByteChannel inputChannel =
Channels.newChannel(Files.newInputStream(path));
WritableByteChannel outputChannel = Channels.newChannel(output)) {
ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
while (inputChannel.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
}
if
(contentLength == -1 &&
!Faces.getExternalContext().isResponseCommitted()) {
externalContext.setResponseHeader("Content-Length",
String.valueOf(size));
}
}
});
}
Or, you can obtain the same thing by using several OmniFaces utilities:
import
org.omnifaces.util.Callback;
import
org.omnifaces.util.Callback.Output;
import
org.omnifaces.util.Faces;
import
org.omnifaces.util.Utils;
...
public void downloadFile()
throws IOException {
Faces.sendFile("rafaelnadal.png",
true, new Callback.Output() {
@Override
public void writeTo(OutputStream output)
throws IOException {
long size =
Utils.stream(Faces.getResourceAsStream("/resources/default/images/rafa.png"),
output);
if
(!Faces.getExternalContext().isResponseCommitted()) {
Faces.getExternalContext().setResponseHeader("Content-Length",
String.valueOf(size));
}
}
});
}
Niciun comentariu :
Trimiteți un comentariu