Я сделал шаг 4 несколько недель назад, и позвольте мне дать вам несколько советов:
Используйте компонент html tag ссылки.Для этого я рекомендую компонент тега a4j:htmlCommandLink
(он похож на обычный h:commandLink
с той разницей, что компоненты <f:param />
всегда отображаются, вы можете проверить больше в документации компонента ).
Если вы не знаете тип файла для загрузки (), вы должны установить Контент как application / octet-stream .
После настройки файла для загрузки в ваш ответ, вы должны установить, что ответ был завершен.
Для этого я добавлю свой код Backing Beanзапрос:
public void descargaArchivo() {
//sorry but the programming standard says that we MUST declare
//our variables at the beginning of any function =(
HttpServletResponse objResponse;
FileInputStream objFileInputStream;
String strNombreCompletoArchivo, strNombreArchivo;
byte[] arrDatosArchivo;
try {
//Here I get the <f:param> with the full name of the file. It encapsulates
// the Faces.getCurrentInstance... call.
strNombreCompletoArchivo = UManejadorSesionWeb.obtieneParametro("nombreCompletoArchivo");
//The function obtieneNombreArchivo retrieves the name of the file
//based on the full name and the file separator (/ for Windows, \ for Linux)
strNombreArchivo = UFuncionesGenerales.obtieneNombreArchivo(strNombreCompletoArchivo);
//Getting the response from Faces.getCurrentInstance...
objResponse = UManejadorSesionWeb.obtieneHttpResponse();
//Setting up the response content type and header (don't set the length!)
objResponse.setContentType("application/octet-stream");
objResponse.setHeader("Content-Disposition", "attachment; filename=\"" + strNombreArchivo + "\"");
//Create the FileInputStream for the file to download
objFileInputStream = new FileInputStream(strNombreCompletoArchivo);
//Setting the file on the response
arrDatosArchivo = new byte[UConstante.BUFFER_SIZE];
while(objFileInputStream.read(arrDatosArchivo, 0, UConstante.BUFFER_SIZE) != -1) {
objResponse.getOutputStream().write(arrDatosArchivo, 0, UConstante.BUFFER_SIZE);
}
objFileInputStream.close();
objResponse.getOutputStream().flush();
objResponse.getOutputStream().close();
//Telling the framework that the response has been completed.
FacesContext.getCurrentInstance().responseComplete();
} catch (Exception objEx) {
//manage the errors...
}
}
//The constant used for byte array size
public class UConstante {
public static final int BUFFER_SIZE = 2048;
}
Фрагмент jsp, который я использовал, выглядит следующим образом:
<a4j:htmlCommandLink rendered="#{documento.rutaDestino != null}"
action="#{documentoRequerido.descargaArchivo}">
<f:param name="nombreCompletoArchivo" value="#{documento.rutaDestino}" />
<h:graphicImage value="/Resource/iconos/mover-abajo.png" styleClass="pic" />
</a4j:htmlCommandLink>
Надеюсь, это поможет вам.
РЕДАКТИРОВАТЬ: у меня было немного свободного времени, извините, номы немного заняты в проекте.Код Java был обновлен и протестирован в IE8, Firefox 9 и 10 и Chrome 16. Что касается значения константы размера буфера, я провел небольшое исследование и нашел хороший ответ на этом сайте.
PS: Я не воспринимаю это как соревнование, я просто стараюсь помогать людям, когда могу.Если мой код не очень хорош, спасибо, что сообщили мне об этом, это лучший способ для всех расти лучше и здоровее:).
РЕДАКТИРОВАТЬ: Благодаря @ lisa
Toдобиться следующего вручную, просто изменив эту часть во фрагменте
//strNombreCompletoArchivo = UManejadorSesionWeb.obtieneParametro("nombreCompletoArchivo");
String parameterStr = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap.get("nombreCompletoArchivo");
strNombreCompletoArchivo = parameterStr;