Загрузите файл с помощью JSF?

который является правильным способом загрузки файла с помощью JSF?, просто поместив ссылку на файл? в этом случае, как получить URL-адрес файла?

Я видел один пример с использованием BufferedInputStream:

http://www.winstonprakash.com/articles/jsf/file_download_link.htm

В чем отличия?

Спасибо

Ответы

Ответ 1

Если это простой файл, просто разместите его в общедоступном webcontent (там, где вы ставите свои статические и JSF файлы) и создаете ссылку.

<h:outputLink value="/files/file.ext">link</h:outputLink>

Сервлетконтейнер будет беспокоиться о применении правильных заголовков.

Если он находится за пределами общедоступного webcontent по некоторым конкретным причинам (например, по фиксированному пути на серверной машине или в базе данных), тогда создайте сервлет, который получает InputStream и записывает его в OutputStream ответа по крайней мере на Content-Type, Content-Disposition и Content-Length. Вы можете найти здесь простой пример запуска. Также это можно просто связать с сервлетами url-pattern.

Если он будет динамически генерироваться и зависит от специфических параметров запроса JSF, вы также можете сделать это в управляемом действии bean, которое связано с h:commandLink или h:commandButton, но вам нужно только убедиться, что вы вызываете FacesContext#responseComplete() в конце метода действия bean, чтобы предотвратить JSF от навигации в руках. Такой же код сервлета можно повторно использовать для потоковой передачи файла. Вы можете найти пример запуска в этом ответе.

Ответ 2

Мне нужно было сделать аналогичный код для загрузки файла через JSF

Что моя кнопка загрузки на моей странице JSF

<h:commandButton value="Download" action="#{helloBean.downloadFile}" />

И это мой код Java

public void downloadFile() {

    File file = new File("/home/marco/file.txt");
    HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();  

    response.setHeader("Content-Disposition", "attachment;filename=file.txt");  
    response.setContentLength((int) file.length());  
    ServletOutputStream out = null;  
    try {  
        FileInputStream input = new FileInputStream(file);  
        byte[] buffer = new byte[1024];  
        out = response.getOutputStream();  
        int i = 0;  
        while ((i = input.read(buffer)) != -1) {  
            out.write(buffer);  
            out.flush();  
        }  
        FacesContext.getCurrentInstance().getResponseComplete();  
    } catch (IOException err) {  
        err.printStackTrace();  
    } finally {  
        try {  
            if (out != null) {  
                out.close();  
            }  
        } catch (IOException err) {  
            err.printStackTrace();  
        }  
    }  

}

Ответ 3

У меня была ошибка на

FacesContext.getCurrentInstance().getResponseComplete(); 

от типа

java.lang.IllegalStateException: getOutputStream() has already been called for this response 

и я решил:

Страница JSF:

<h:commandButton action="#{bean.downloadFile}" id="downloadBtn" value="Download"/>

Bean метод:

public void downloadFile(File file) {   
    FacesContext facesContext = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
    response.setHeader("Content-Disposition", "attachment;filename=file.txt");
    response.setContentLength((int) file.length());
    FileInputStream input= null;
    try {
        int i= 0;
        input = new FileInputStream(file);  
        byte[] buffer = new byte[1024];
        while ((i = input.read(buffer)) != -1) {  
            response.getOutputStream().write(buffer);  
            response.getOutputStream().flush();  
        }               
        facesContext.responseComplete();
        facesContext.renderResponse();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(input != null) {
                input.close();
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}