Подтвердить что ты не робот

Отображение изображений blob в папке <p: graphicImage> внутри <ui: repeat>

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

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

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

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

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

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

SEVERE [org.primefaces.application.PrimeResourceHandler] (http-127.0.0.1-8080-12) Ошибка в потоковом динамическом ресурсе.

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

4b9b3361

Ответ 1

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

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

например.

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

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

@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>, который можно использовать более интуитивно, почти по-разному, как вы ожидали. См. Также в блоге по этому вопросу.

См. также:

Ответ 2

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

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

JSF - отображение изображений из базы данных в JSF

Ответ 3

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

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

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

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

 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");
    }

Теперь он работает хорошо.

Ответ 4

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

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

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

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

Ответ 5

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

на странице jsf;

<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />

Ответ 6

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