问题
I was wondering if and how it is possible to display an <o:graphicImage>
as thumbnail inside a <p:lightbox>
. To be more precise, I wanted to achieve something like this:
<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>
Which isn't working obviously, since there's no proper URL passed to the lightbox.
imageBean.getFirstImage(Article article, boolean thumbnail)
returns a byte[]
of the image, since the images I want to access are stored on an external source.
Edit: So I've done as BalusC mentioned and it seems to be the proper approach. But now I'm getting the following exception:
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
This is the method that actually returns the image. It is working fine in every other context:
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];
}
}
Edit 2: As mentioned in the comments, I'm facing another weird behaviour. It runs perfectly fine on my local machine but on the server it throws following exception:
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:
For exactly this reason, OmniFaces 2.5 introduced the #{of:graphicImageURL()}
EL function. This works only if your ImageBean
is annotated with @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>
See also the @GraphicImageBean showcase.
Update: to be clear, you need a converter for non-standard types such as Article
. Why such a converter is needed and how to create it is detailed in Conversion Error setting value for 'null Converter'. If you create a @FacesConverter(forClass=Article.class)
, then the OmniFaces GraphicImage
will automatically pickup it.
In your particular case it's however more efficient to just pass the identifier to the image streamer method right away, this saves an additional conversion step. Provided that your Article
object has an id
property, here's how:
<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) {
// ...
}
Namely, JSF already has builtin converters for standard types such as Long
and boolean
.
来源:https://stackoverflow.com/questions/39736390/how-to-create-a-thumbnail-link-to-omnifaces-graphicimage-method