2016-08-07 11 views
5

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

Вот 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 не найденную ошибку.

+0

Вы говорите, что загрузка работает так, как этот вопрос [тег: файл-загрузка], связанные и не [теги: графический образ] – Kukeltje

+0

потому что 'байты []' источник пришли из содержания загрузки, так я получил загружаемый контент 'byte []', но когда я использую загружаемый контент для отображения на веб-странице, он не будет отображаться и говорить, что ресурс не найден –

+0

Итак, вы имеете в виду, что если вы вручную ставите байт [] в базе данных, а не через загрузку файла, он работает? – Kukeltje

ответ

6

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

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

private UploadedFile uploadedFile; 
private byte[] fileContents; 

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

// ... 

Чтобы решить вторую проблему, вам лучше всего использовать данные схемы URI. Это позволяет визуализировать изображение непосредственно в одном и том же ответе, и поэтому вы можете безопасно использовать bean-компонент @ViewScoped без проблем «контекст неактивен» или сохранения byte[] в сеансе или диске, чтобы включить показ изображения в другом запросе , Browser support on data URI scheme в настоящее время довольно хорошо. Заменить весь <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).

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

<o:graphicImage value="#{bean.imageContents}" dataURI="true" rendered="#{not empty bean.imageContents}"> 
+0

Спасибо @BalusC вопрос сейчас был полностью проверен и был разрешен в соответствии с вашим решением, очень спасибо вашим усилиям –

+0

Добро пожаловать. – BalusC

+0

Вы потрясающий @BalusC! – Dandelion