Отображение изображений блобов базы данных в <p:graphicImage> внутри <ui:repeat>

Я использую PrimeFaces 3.2 на JBoss 7.1.1.

Я пытаюсь отобразить изображение, которое хранится в BLOB в базе данных MySQL в<ui:repeat>, Изображение хранится вbyte[] а затем преобразован вStreamedContent следующее:

<code>InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));
</code>

Затем я пытаюсь отобразить его в Facelet следующим образом:

<code><ui:repeat var="ingredient" value="#{formBean.ingredientResultSet}">
    <p:panel id="resultsPanel" header="#{ingredient.location.shopName}">
        <p:graphicImage value="#{ingredient.jsfImage}" alt="No picture set" />
...
</code>

Однако при загрузке страницы я получаю следующую ошибку в JBoss:

SEVERE [org.primefaces.application.PrimeResourceHandler] (http--127.0.0.1-8080-12) Error in streaming dynamic resource.

Как это вызвано и как я могу решить это?

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

зачем тебе это. Вы можете просто создать сервлет, который будет получать изображение из базы данных с помощью сопоставления & quot; /images/yourimage.jpg" ;.

Вот краткое руководство с соответствующим кодом о том, как это сделать.

JSF - Displaying images from database in JSF

 25 июн. 2015 г., 12:59
Да, это умное решение, особенно для SEO-решений.

<p:graphicImage не работает с пользовательским интерфейсом: повторяю, у вас будет много проблем с этим (поскольку я сделал XD), я рекомендую вам создать сервлет и использовать изображения в качестве входного потока (существует множество примеров).

InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");

<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />
Решение Вопроса

<p:graphicImage> на самом деле оказывает<img src> элемент с только URL, который затем индивидуально вызывается веб-браузером, когда он собирается проанализировать полученную разметку HTML и представить результаты.

Итак, что бы вы ни делали в методе получения<p:graphicImage> он должен быть спроектирован таким образом, чтобы его можно было вызывать для каждого запроса. Таким образом, самый разумный подход заключается в создании<p:graphicImage> с<f:param> где<p:graphicImage value> указывает на полностью автономный запрос или область приложения, и<f:param value> указывает уникальный идентификатор изображения.

Например.

<p:graphicImage value="#{images.image}">
    <f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>

ГдеImages боб может выглядеть так:

@ManagedBean
@ApplicationScoped
public class Images {

    @EJB
    private ImageService service;

    public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
            // So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
            return new DefaultStreamedContent();
        }
        else {
            // So, browser is requesting the image. Return a real StreamedContent with the image bytes.
            String id = context.getExternalContext().getRequestParameterMap().get("id");
            Image image = service.find(Long.valueOf(id));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}

Или, если вы уже используетеOmniFaces 2.0 или новеезатем рассмотрите возможность использования его<o:graphicImage> вместо этого, который можно использовать более интуитивно, почти точно так, как вы ожидали. Смотрите такжеблог на предмет.

See also: Display dynamic image from database with p:graphicImage and StreamedContent
 03 мая 2016 г., 09:04
Не могли бы вы показать, какImageService должен выглядеть?
 03 мая 2016 г., 09:06
@John: это просто класс обслуживания / DAO, который возвращает вашImage юридическое лицо. То, как она выполняет свою работу (JPA, JDBC, Hibernate, что угодно), не представляет интереса для JSF.

определив целое число в базовом компоненте и присвоив ему другое значение при обновлении ByteArray для изображения. Это целое число служит уникальным идентификатором изображения. Затем я устанавливаю это целое число как значение<f:param> в<p:graphicImage> на странице.

тег изображения выглядит

 <p:graphicImage value="#{empBean.image}">
    <f:param name="id" value="#{empBean.imageId}" />
  </p:graphicImage>`

и установка изображения в бобе как

 if(user.getPicture()!=null){
        imageId = (int) new Date().getTime();
        BinaryStreamImpl bs = new BinaryStreamImpl(user.getPicture());  
//picture is byte[] property in user class      
        this.image =   new DefaultStreamedContent(bs.getInputStream(), "image/png");
    }

Сейчас хорошо работает.

graphicImage Компонент отображается на странице. Это делает HTML<img> элемент. В браузере будет сделан запрос для страницы JSF, затем последующие запросы будут также выполняться для каждого из изображений на странице.

Эти изображения поступают из сервлета ресурсов PrimeFaces, а не FacesServlet, что означает, что область действия управляемого объекта и его свойств, вероятно, не применима.

Попробуйте сначала загрузить большой двоичный объект в байтовый массив, после чего это, вероятно, начнет работать.

EDIT: Смотрите мой следующий ответ на этот похожий вопрос.графическое изображение не отображает потоковое содержимое в Primefaces

 Gonzalo Garcia Lasurtegui09 апр. 2012 г., 17:37
Спасибо за ответ, но согласно моему описанию выше, изображение уже является байтом []

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