如何创建缩略图 link 到 OmniFaces graphicImage 方法
How to create a thumbnail link to OmniFaces graphicImage method
我想知道是否以及如何在 <p:lightbox>
中显示 <o:graphicImage>
作为缩略图。更准确地说,我想实现这样的目标:
<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)
returns 图像的 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
这是实际returns图像的方法。它在所有其他情况下都运行良好:
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
正是出于这个原因,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>
另见 the @GraphicImageBean
showcase。
Update:明确地说,你需要一个非标准类型的转换器,比如Article
。为什么需要这样的转换器以及如何创建它在 Conversion Error setting value for 'null Converter' 中有详细说明。如果您创建一个 @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
等标准类型的转换器。
我想知道是否以及如何在 <p:lightbox>
中显示 <o:graphicImage>
作为缩略图。更准确地说,我想实现这样的目标:
<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)
returns 图像的 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
这是实际returns图像的方法。它在所有其他情况下都运行良好:
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
正是出于这个原因,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>
另见 the @GraphicImageBean
showcase。
Update:明确地说,你需要一个非标准类型的转换器,比如Article
。为什么需要这样的转换器以及如何创建它在 Conversion Error setting value for 'null Converter' 中有详细说明。如果您创建一个 @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
等标准类型的转换器。