【问题标题】:How to create a thumbnail link to OmniFaces graphicImage method如何创建指向 OmniFaces graphicsImage 方法的缩略图链接
【发布时间】:2017-02-05 18:39:57
【问题描述】:

我想知道是否以及如何将<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: 如 cmets 所述,我正面临另一种奇怪的行为。它在我的本地机器上运行得很好,但在服务器上却抛出了以下异常:

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

【问题讨论】:

标签: jsf thumbnails omnifaces graphicimage


【解决方案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>

另见the @GraphicImageBean showcase


更新:需要明确的是,您需要一个非标准类型的转换器,例如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 已经内置了标准类型的转换器,例如Longboolean

【讨论】:

  • 谢谢,我很确定这是正确的方法,但它一直告诉我'javax.el.E​​LException:函数of:graphicImageURL' not found。我确信我以正确的方式包含了omnifaces,因为wildfly在服务器启动时告诉我08:42:29,600 INFO [org.omnifaces.ApplicationInitializer] (ServerService Thread Pool -- 68) Using OmniFaces version 2.5.1
  • 如果模板中缺少 XML 命名空间声明 xmlns:of="http://omnifaces.org/functions",就会发生这种情况。
  • 谢谢,这至少解决了这个问题。现在,缩略图像往常一样显示,但灯箱仍然没有显示任何图像(微调器一直在旋转)。我也得到一个例外说:2016-09-28 15:04:52,091 ERROR [io.undertow.request] (default task-21) UT005023: Exception handling request to /ToyJoTCS/javax.faces.resource/ImageBean_getFirstImage.xhtml: javax.servlet.ServletException: java.lang.ClassCastException@4cdaa9e4 ... Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@4cdaa9e4
  • 像往常一样,答案在堆栈跟踪中。
  • 我可以从该堆栈跟踪中提取的是,某些东西想要被转换成它不能被转换的东西。对我来说也很奇怪的是request to /ToyJoTCS/javax.faces.resource/ImageBean_getFirstImage.xhtml‌​: 。很抱歉被这个问题难住了,但我不明白。我想,of:graphicImageURL() 会接受一个返回 byte[] 的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
相关资源
最近更新 更多