是否有关于获取< p:graphicImage>的URL的新闻? [英] Is there news on getting the URL of <p:graphicImage>?

查看:68
本文介绍了是否有关于获取< p:graphicImage>的URL的新闻?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我的问题与五年前回答的这个问题相同:我想输出一个服务器提供的图像(来自<p:graphicImage>),只是URL,而不是<img>标记.我正在寻找的是这样的解决方案:

Basically my question is the same as this one answered five years ago: I would like to output the URL of a server-provided image as from <p:graphicImage>, but just the URL and not an <img> tag. What I am looking for is a solution like this:

(这是不起作用的代码,只是为了说明:)

(This is not working code, just to illustrate:)

<p:graphicImage var="url" value="#{MyForm.image}"/>
<span id="imageData" data-image="#{url}/>

应该将以下内容输出到HTML:

Which should output to the HTML like this:

<span id="imageData" data-image="http://localhost:8080/contextPath/javax.faces.resource/dy...

我目前正在为此使用 JavaScript解决方法,但是这种要求对我来说似乎太普遍了,以至于我会期望新的开发已经针对它,并且有一个内置的解决方案.自最近五年以来,有没有关于该主题的新闻?

I am currently using a JavaScript work-around for this, but this requirement seems so common to me that I would expect newer development has already targeted it and there is a built-in solution. Is there news on that topic since the last five years?

推荐答案

只需看一下 DynamicContentSrcBuilder :

Just took a look at the GraphicImageRenderer wanting to figure out how they produce that dynamic URL. They are using a static method on their DynamicContentSrcBuilder:

protected String getImageSrc(FacesContext context, GraphicImage image) throws Exception {
    String name = image.getName();

    if (name != null) {
        // ...
    } else {
      return DynamicContentSrcBuilder.build(context, image.getValue(), image, image.isCache(), DynamicContentType.STREAMED_CONTENT, image.isStream());
    }
}

那么为什么不只在p:graphicImage组件上重现此调用呢? 我首先将其bind赋予RequestScoped bean的属性,然后从该bean获取URI,该URI再现了上面显示的渲染器的行为:

So why not just reproduce this call on the p:graphicImage component? I'll first bind it to a property of a RequestScoped bean and then get the URI from that bean which reproduces behavior of the renderer shown above:

XHTML代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<h:head/>
<body>
    <p:graphicImage binding="#{myBean.imgComponent}"
        value="#{myBean.img}" />
    <h:outputText id="imageData" pt:data-image="#{myBean.getImgUri()}" />
</body>
</html>

我的豆又名myBean:

package test;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;

import org.primefaces.application.resource.DynamicContentType;
import org.primefaces.component.graphicimage.GraphicImage;
import org.primefaces.model.StreamedContent;
import org.primefaces.util.DynamicContentSrcBuilder;

@Named
@RequestScoped
public class MyBean {

    private GraphicImage imgComponent;

    private String imgUri;

    public StreamedContent getImg() throws IOException {
        // ...
    }

    public GraphicImage getImgComponent() {
        return imgComponent;
    }

    public void setImgComponent(GraphicImage imgComponent) {
        this.imgComponent = imgComponent;
    }

    public String getImgUri() throws UnsupportedEncodingException {
        assert null != imgComponent;
        if (null == imgUri) {
            // here we reproduce the GraphicImageRenderer behavior:
            imgUri = DynamicContentSrcBuilder.build(FacesContext.getCurrentInstance(), imgComponent.getValue(),
                    imgComponent, imgComponent.isCache(), DynamicContentType.STREAMED_CONTENT, imgComponent.isStream());
        }
        return imgUri;
    }

}

或者,我们可以使用 GraphicImageRenderer并发布protected方法getImageSrc:

Alternatively we can use the GraphicImageRenderer and publish the protected method getImageSrc:

public class MyBean {
  // ...
  public String getImgUri() throws Exception {
    assert null != imgComponent;
    if (null == imgUri) {
        imgUri = new GraphicImageRendererXtension().getPublicImageSrc(FacesContext.getCurrentInstance(),
                imgComponent);
    }
    return imgUri;
  }
}

public class GraphicImageRendererXtension extends GraphicImageRenderer {
    // publish the protected GraphicImageRenderer#getImageSrc method:
    public String getPublicImageSrc(FacesContext context, GraphicImage image) throws Exception {
        return getImageSrc(context, image);
    }
}

但是为什么我写#{myBean.getImgUri()}而不是#{myBean.imgUri}?我仍然不确定,但是使用后者会产生PropertyNotFoundException:

But why did I write #{myBean.getImgUri()} instead of #{myBean.imgUri}? I'm still not sure, but using the latter produces a PropertyNotFoundException:

javax.el.PropertyNotFoundException: /myView.xhtml @20,46 value="#{myBean.imgUri}": ELResolver did not handle type: [null] with property of [imgUri]
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:117)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:200)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:187)
    at javax.faces.component.UIOutput.getValue(UIOutput.java:179)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:360)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:171)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:86)
    at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:73)
    at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:49)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:491)
    at javax.faces.view.ViewDeclarationLanguageWrapper.renderView(ViewDeclarationLanguageWrapper.java:126)
...
Caused by: javax.el.PropertyNotFoundException: ELResolver did not handle type: [null] with property of [imgUri]
    at org.apache.el.parser.AstValue.getValue(AstValue.java:174)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:190)
    at org.apache.webbeans.el22.WrappedValueExpression.getValue(WrappedValueExpression.java:68)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:115)
    ... 122 more

可能调用DynamicContentSrcBuilder.build()方法会以某种方式弄乱正在进行的值表达式#{myBean.imgUri}的解析,而#{myBean.getImgUri()}不会受到影响.

Possibly invoking the DynamicContentSrcBuilder.build() method somehow messes up the ongoing resolving of the value expression #{myBean.imgUri}, while #{myBean.getImgUri()} is not affected.

回到您的问题:没有新闻.构建动态URI,并在渲染时将其直接发送到浏览器. GraphicImage组件对此没有提供任何吸气剂.我在这里介绍的是一种服务器端变体,无需创建新的servlet.

Getting back to your question: no there is no news. The dynamic URI is built and directly sent to the browser while rendering. The GraphicImage component does not provide any getter for this. What I presented here is a server side variant of a work around without the need to create a new servlet.

当然,您还可以参数化getImageUri方法并将Image组件绑定到某个任意变量,这将使您更接近于演示var="..."示例:

Of course you can also parameterize the getImageUri method and bind your Image component to some arbitrary variable which would bring you closer to your demonstration var="..." example:

public class MyBean {
  // ...
  public String getImgUri(GraphicImage imgComponent) throws Exception {
    assert null != imgComponent;
    String imgUri = new GraphicImageRendererXtension().getPublicImageSrc(FacesContext.getCurrentInstance(),
                imgComponent);
    return imgUri;
  }
}

然后通过以下方式使用此方法:

Then use this method by:

<p:graphicImage binding="#{myImage}" value="#{myBean.img}" />
<h:outputText id="imageData" pt:data-image="#{myBean.getImgUri(myImage)}" />

这样,无需为每个图像创建一个bean或方法.

This way there's no need to create a bean or method for each image.

这篇关于是否有关于获取&lt; p:graphicImage&gt;的URL的新闻?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆