Как использовать ‹p:graphicImage› с DefaultStreamedContent в ui:repeat?

Я пытался отобразить панель, на которой пользователь может видеть список категорий товаров (отображаемых в виде изображений), и при нажатии они могут просматривать продукты в категории (изображения будут отображаться)

Для отображения категории элемента я использовал ui:repeat nad поддерживающий bean-код. Ниже приведен мой код xhtml.

<ui:repeat id="repeat" value="#{getData.images}" var="img" varStatus="loop">
<h:panelGroup>
<p:graphicImage id="img1" value="#{img}" alt="image not available" >
</p:graphicImage>
</h:panelGroup>
</ui:repeat>

И части кода управляемого компонента

private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private List<StreamedContent> imageList = new ArrayList<StreamedContent>();

public List<StreamedContent> getImages(){
  for (int i = 0; i < sdh.getNumOfImages(); i++) {
    imageID = imageIDArray.get(i);
    ImageService imgSer = new ImageService();
    imgList.add(imageID);
    imgSer.setData(imageID);
    baos = imgSer.getImage();
    try {
      imageList.add(new DefaultStreamedContent(new 
            ByteArrayInputStream(baos.toByteArray())));
    } catch (Exception ex) {
        ex.printStackTrace();
    }
  }
  imageNum = 0;
  return imageList;
}

public StreamedContent getData() {
    baos = imageList.get(imageNum);
    //imageList.add(baos);
    imageNum++;
    return new DefaultStreamedContent(new ByteArrayInputStream(baos.toByteArray()));
}

Теперь моя проблема, если я не раскомментирую «imageList.add(baos)» в «getData», изображения не отображаются. Теперь я действительно хочу знать, как работает 'ui:repeat', поскольку 'imageList' содержит изображения, и я могу сохранить их, если это необходимо, в любом из методов. Если я укажу фиксированное число (например: 'imageList.get(0)') в методе 'getData', то одно и то же изображение будет отображаться несколько раз. Где, как если бы я поместил «imageNum» без «imageList.add (baos)», он выдает ошибку «Ошибка в потоковом динамическом ресурсе»

Я устал от предложения Бьорна Поллекса и внес необходимые изменения, но теперь изображения не появляются.


person user1433804    schedule 08.06.2012    source источник
comment
Вы не ссылаетесь на переменную цикла (img в вашем случае) внутри вашего <ui:repeat>. Ваш getImages должен вернуть List<StreamedContent>, а ваш <p:graphicImage> должен вернуть value="#{img}".   -  person Björn Pollex    schedule 08.06.2012


Ответы (2)


Невозможно использовать <p:graphicImage> таким образом. Вам следует перебирать набор уникальных идентификаторов изображений, а не набор StreamedContent. Затем эти уникальные идентификаторы изображений должны быть переданы как <f:param> в <p:graphicImage>, что, в свою очередь, сгенерирует правильные URL-адреса для браузера.

<ui:repeat value="#{data.imageIds}" var="imageId">
    <p:graphicImage value="#{imageStreamer.image}">
        <f:param name="id" value="#{imageId}" />
    </p:graphicImage>
</ui:repeat>

Ваш #{data} управляемый компонент должен иметь только:

private List<Long> imageIds; // +getter

#{imageStreamer} должен быть отдельным управляемым компонентом с областью действия приложения, который выглядит примерно так:

@ManagedBean
@ApplicationScoped
public class ImageStreamer {

    @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. Get ID value from actual request param.
            String id = context.getExternalContext().getRequestParameterMap().get("id");
            Image image = service.find(Long.valueOf(id));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}
person BalusC    schedule 08.06.2012
comment
hankyou BalusC, это сработало, но мне пришлось прокомментировать @EJB, если я этого не сделаю, я получу com.sun.faces.mgbean.ManagedBeanCreationException: произошла ошибка при выполнении инъекции ресурсов в управляемый компонент imageStreamer. У меня есть еще один вопрос › Когда я обновляю страницу пропадают изображения, почему так. Еще раз спасибо - person user1433804; 08.06.2012
comment
Пожалуйста. Ну, я просто предположил, что вы используете EJB для бизнеса/служб данных. Он обеспечивает простой и безопасный способ прозрачной обработки транзакций БД. Если вы не используете его, просто сделайте так, как обычно, чтобы получить услугу. - person BalusC; 08.06.2012
comment
Еще один вопрос, если мне нужно получить событие клика по изображению, то как мне это сделать. Я не могу поместить Ajax в ui:repeat. - person user1433804; 09.06.2012
comment
@BalusC, как вернуть ошибку 404, если изображение не найдено? - person TecHunter; 07.08.2017

Вы использовали неправильный тег ui:repeat. У вас есть атрибут var, но вы не можете использовать его в атрибуте значения тега p:graphicImage. См. пример использования,

       <ui:repeat value="#{yourBean.images}" var="img">
           <p:graphicImage value="/images/#{img}" />
        </ui:repeat>
person Sai Ye Yan Naing Aye    schedule 08.06.2012