В настоящее время я сталкиваюсь со странной проблемой на своей веб-странице на устройствах Android.
Я хочу разрешить пользователю загружать pdf-файл на свое мобильное устройство.Поэтому я предоставляю кнопку загрузки, как в настройке, описанной здесь .
Все работает нормально, пока я использую свой настольный браузер * Mozilla Firefox 10. **, но как только я перехожу намое мобильное устройство (SGS II, версия Android 2.3.5) результат загрузки зависит от используемого мной браузера-приложения.
Mozilla и Opera mobile:
Кажется, что оба файла могут правильно загрузить файл.
Любое другое браузерное приложение (встроенное, Dolphin HD, ...):
Загружает файл с именем <filename>.pdf
или <filename>.htm
, который представляет файл .htm , показывающий html-источник страницы.
Что я пробовал:
Использовал метод StreamedContent
из библиотеки PrimeFaces
public StreamedContent getFile() {
// prepare file for download
// reference webDAV directory and get file as stream
this.file = new Helper().getWebDavFile(customerId, fileName);
return file;
}
Потоковый файлвручную на страницу, как описано здесь .(Thx в BalusC)
public void download() throws IOException {
byte[] is = new Helper().getWebDavFileManually(customerId, fileName);
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/pdf");
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName.toUpperCase() + "\"");
OutputStream output = ec.getResponseOutputStream();
output.write(is);
fc.responseComplete();
}
Установите <a href="">
для локальной копии файла.
(В настоящее время я использую <p:commandButton>
, поэтому яиспользовать метод, выполняющий перенаправление вместо возврата строки, но он работает в обоих направлениях)
public void goToLink() throws IOException {
// get WebDAV file and save temporarily
byte[] b = new Helper().getWebDavFileManually(customerId, fileName);
String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/") + fileName;
File f = new File(path);
try {
FileOutputStream fos = new FileOutputStream(f);
fos.write(b);
link = "http://someurl/somepage/" + fileName;
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
// use link
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(link);
}
Этот последний подход хорошо работал даже на моем устройстве Android, но я не хочу идите по этому пути, если я могу избежать этого, потому что файл передается через WebDAV, и я должен был бы сохранить каждый файл на сервере.Это увеличит нагрузку ввода-вывода и вынудит меня выполнить очистку вручную.
Методы Helper().getWebDavFile
и Helper().getWebDavFileManually
либо возвратят DefaultStreamedConten , используемый PrimeFacesили байт [] для моего собственного подхода.
Что я знаю до сих пор:
К сожалению, не решение моей проблемы :).
После многих часов использования Google я обнаружил, что существует возможность double-http-post-request .Это приведет к тому, что внутренний менеджер загрузок Android (используемый в случае загрузки поврежденного файла) отправит дополнительный пост-запрос, в котором состояние будет потеряно.
Как описано в этом блоге (см. Раздел GET, POST, REST [ОБНОВЛЕНИЕ 20120208] ) есть кто-то, кто сталкивается с той же проблемой.Я перепробовал все подходы, упомянутые в этом блоге, но безуспешно.
На этом форуме кто-то проанализировал такое же поведение с WireShark и пришел почти к тому же выводу.
Я не нашел больше ресурсов, поэтому я застрял в этом.
Я также разместил сообщение на форуме PrimeFaces , просто чтобы убедиться, что нет ни одного известногопроблемы, связанные с <p:fileDownload>
компонентом.
Что я хотел бы знать:
Я что-то упустил?
Есть ли возможность загрузить потоковый файлс веб-страницы JSF (работающей по протоколу http) на устройстве Android?
Буду признателен за любую помощь / предложение / информацию!
Заранее спасибо!