Как создать ссылку на миниатюру для метода OmniFaces graphicImage

Мне было интересно, если и как можно отобразить <o:graphicImage> как миниатюра внутри <p:lightbox>, Чтобы быть более точным, я хотел добиться чего-то вроде этого:

<p:dataTable id="articles" var="article"
  value="#{articleMB.articles}" selectionMode="single"
  rowKey="#{articles.id}"
  selection="#{articleMB.selectedArticle}">
  <p:column>
    <p:lightBox styleClass="imagebox" id="lighbox">  
      <h:outputLink value="#{imageBean.getFirstImage(article, true)}">  
        <o:graphicImage value="#{imageBean.getFirstImage(article, true)}" dataURI="true" height="80" />  
      </h:outputLink>
     </p:lightBox>
   </p:column>
</p:dataTable>

Который не работает, очевидно, так как нет правильного URL, переданного в лайтбокс. imageBean.getFirstImage(Article article, boolean thumbnail) возвращает byte[] изображения, так как изображения, к которым я хочу получить доступ, хранятся во внешнем источнике.


Изменить: Итак, я сделал, как упомянул BalusC, и, похоже, это правильный подход. Но теперь я получаю следующее исключение:

Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@2eae887c 
    at sun.reflect.GeneratedMethodAccessor307.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.omnifaces.resourcehandler.GraphicResource.getInputStream(GraphicResource.java:259) 
    at com.sun.faces.application.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:335) 
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153) 
    at org.primefaces.application.resource.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:87) 
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153) 
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:655) 
    ... 32 more

Это метод, который на самом деле возвращает изображение. Работает нормально в любом другом контексте:

public byte[] getFirstImage(final Article article, boolean thumbnail)
{
    try
    {
        File dir = new File(getImageFolder(article.getImageFolder(), thumbnail));
        File[] files = dir.listFiles(new FilenameFilter()
        {
            @Override
            public boolean accept(File dir, String name)
            {
                return name.startsWith(String.valueOf(article.getArticleId()));
            }
        });
        Arrays.sort(files);
        return Files.readAllBytes(files[0].toPath());
    }
    catch (Exception e)
    {
        return new byte[1];
    }
}

Редактировать 2: Как уже упоминалось в комментариях, я столкнулся с другим странным поведением. Он отлично работает на моей локальной машине, но на сервере выдает следующее исключение:

Caused by: java.lang.IllegalArgumentException: argument type mismatch
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.omnifaces.resourcehandler.GraphicResource.getInputStream(GraphicResource.java:259)
    at com.sun.faces.application.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:335)
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153)
    at org.primefaces.application.resource.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:87)
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153)
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:153)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:655)
    ... 32 more

1 ответ

Решение

Именно по этой причине OmniFaces 2.5 представила #{of:graphicImageURL()} EL функция. Это работает, только если ваш ImageBean помечен @GraphicImageBean,

import org.omnifaces.cdi.GraphicImageBean;

@GraphicImageBean
public class ImageBean {

    // ...

}

<h:outputLink value="#{of:graphicImageURL('imageBean.getFirstImage(article, false)')}">  
    <o:graphicImage value="#{imageBean.getFirstImage(article, true)}" dataURI="true" height="80" />  
</h:outputLink>

Смотрите также @GraphicImageBean витрина


Обновление: чтобы быть понятным, вам нужен конвертер для нестандартных типов, таких как Article, Зачем нужен такой конвертер и как его создать, подробно описано в значении параметра "Ошибка преобразования" для "нулевого конвертера". Если вы создаете @FacesConverter(forClass=Article.class)тогда OmniFaces GraphicImage автоматически заберет его.

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

<h:outputLink value="#{of:graphicImageURL('imageBean.getFirstImage(article.id, false)')}">  
    <o:graphicImage value="#{imageBean.getFirstImage(article.id, true)}" dataURI="true" height="80" />  
</h:outputLink>

public byte[] getFirstImage(Long articleId, boolean thumbnail) {
    // ...
}

А именно, JSF уже имеет встроенные конвертеры для стандартных типов, таких как Long а также boolean,

Другие вопросы по тегам