Как создать ссылку на миниатюру для метода 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
,