Отображение p: fileupload изображения в p: graphicImage предварительного просмотра без его сохранения

Я использую PrimeFaces 5.3<p:fileUpload> чтобы загрузить изображение PNG, и я хотел бы показать его предварительный просмотр в<p:graphicImage> перед сохранением в базе данных.

Вот MCVE:

<h:form enctype="multipart/form-data">
    <p:fileUpload value="#{bean.uploadedFile}" mode="simple" />
    <p:graphicImage value="#{bean.image}" />
    <p:commandButton action="#{bean.preview}" ajax="false" value="Preview" />
</h:form>

private UploadedFile uploadedFile;

public UploadedFile getUploadedFile() {
    return uploadedFile;
}

public void setUploadedFile(UploadedFile uploadedFile) {
    this.uploadedFile = uploadedFile;
}

public void preview() {
    // NOOP for now.
}

public StreamedContent getImage() {
    if (uploadedFile == null) {
        return new DefaultStreamedContent(); 
    } else {
        return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()), "image/png"); 
    }
}

На компоненте поддержки не возникает ошибок, и изображение не будет загружаться и отображаться на внешнем интерфейсе. Клиент упоминает, что изображение вернуло ошибку 404 not found.

 Kukeltje07 авг. 2016 г., 22:19
конечно, в более длинном бобе ... Но вы бы хотели?
 Kukeltje08 авг. 2016 г., 00:36
 Lance Zhao Zai07 авг. 2016 г., 22:07
да, правильно, мне интересно, что это «несохраненный» загруженный файл, так как я назначил переменную для временного использования, выполняю постоянное сохранение только после окончательного подтверждения для пользователя.
 Lance Zhao Zai07 авг. 2016 г., 21:55
@BalusC, пожалуйста, просмотрите мой обновленный вопрос, проблема точно такая же
 Lance Zhao Zai07 авг. 2016 г., 22:16
Таким образом, я должен выполнить сохранение файла где-нибудь еще в файловой системе или базе данных? нет способа отобразить изображение без сохранения?
 Kukeltje07 авг. 2016 г., 21:38
То есть вы имеете в виду, что если вы вручную добавляете байт [] в базу данных, а не с помощью файла-загрузки, это работает?
 Lance Zhao Zai07 авг. 2016 г., 22:23
боб более длинной области? Извините, я не очень хорошо понимаю концепцию bean-объекта, пожалуйста, направьте меня
 Lance Zhao Zai07 авг. 2016 г., 21:41
Извините, сэр, вы неправильно поняли мой вопрос, я еще не пробовал базу данных, так как она не работает через загрузку файлов
 Lance Zhao Zai07 авг. 2016 г., 21:57
Я не сохранил загруженный файл, я сохранил его в переменной и повторно использую, как только отправляю на отображение для предварительного просмотра.
 Lance Zhao Zai07 авг. 2016 г., 21:44
Предполагается, что поток будет похож на «Загрузить изображение -> Предварительный просмотр изображения -> Сохранить в базе данных», но на данный момент я не могу просмотреть изображение, потому что содержимое из загрузки изображений не может быть отображено
 Lance Zhao Zai07 авг. 2016 г., 21:37
посколькуbyte[] источник взят из загружаемого контента, поэтому я получил загружаемый контентbyte[], но когда я использую загружаемый контент для отображения на веб-странице, он не будет отображаться и сообщать, что ресурс не найден
 Kukeltje07 авг. 2016 г., 21:23
Вы говорите, что загрузка работает, так как это проблемафайл загружен связанные и неграфические изображения

Ответы на вопрос(1)

Решение Вопроса

потому что содержимое загруженного файла является областью запроса и потому что изображение запрашивается в другом HTTP-запросе. Чтобы лучше понять внутреннюю работу, внимательно прочитайте ответы на следующие тесно связанные вопросы и ответы:

Отображение динамического изображения из базы данных с помощью p: graphicImage и StreamedContentКак правильно выбрать сферу применения бобов?

Чтобы решить первую проблему, вам необходимо прочитать содержимое загруженного файланемедленно в методе действия, связанном с формой отправки. В вашем конкретном случае это будет выглядеть так:

private UploadedFile uploadedFile;
private byte[] fileContents;

public void preview() {
    fileContents = uploadedFile.getContents();
}

// ...

Чтобы решить вторую проблему, лучше всего использовать схему URI данных. Это позволяет визуализировать изображение непосредственно в том же ответе, и поэтому вы можете безопасно использовать@ViewScoped bean, не сталкиваясь с проблемами "context not active" или сохраняяbyte[] в сеансе или на диске, чтобы включить обслуживание изображения в другом запросе.Поддержка браузера по схеме URI данных в настоящее время довольно хорошо. Заменить весь<p:graphicImage> с ниже:

<ui:fragment rendered="#{not empty bean.uploadedFile}">
    <img src="data:image/png;base64,#{bean.imageContentsAsBase64}" />
</ui:fragment>

public String getImageContentsAsBase64() {
    return Base64.getEncoder().encodeToString(imageContents);
}

Примечание: я предполагаю, что Java 8 доступна для вас какjava.util.Base64 был введен только в этой версии. Если вы используете старую версию Java, используйтеDatatypeConverter.printBase64Binary(imageContents) вместо.

В случае, если вы используете библиотеку утилит JSFOmniFacesВы также можете просто использовать его<o:graphicImage> вместо этого компонент, который противоречит<p:graphicImage> способен напрямую ссылаться наbyte[] а такжеInputStream свойство bean и отображение URI данных.

<o:graphicImage value="#{bean.imageContents}" dataURI="true" rendered="#{not empty bean.imageContents}">
 BalusC09 авг. 2016 г., 09:16
Пожалуйста.
 BalusC01 янв. 2017 г., 15:52
@ Одуванчик: спасибо :)
 Lance Zhao Zai09 авг. 2016 г., 06:50
Спасибо @BalusC, теперь проблема полностью проверена и решена в соответствии с вашим подходом, благодаря вашим усилиям
 Dandelion01 янв. 2017 г., 13:56
Вы потрясающий @BalusC!

Ваш ответ на вопрос