Есть ли новости о получении URL? - PullRequest
0 голосов
/ 04 марта 2019

По сути, мой вопрос такой же, как и , на который ответил пять лет назад: я хотел бы вывести URL-адрес предоставленного сервером изображения, начиная с <p:graphicImage>, но только URL, а не <img> тег.То, что я ищу, - это решение вроде этого:

(Это неработающий код, просто для иллюстрации:)

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

, которое должно выводиться в HTMLкак это:

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

В настоящее время я использую для этого обходной путь JavaScript , но это требование кажется мне настолько общим, что я ожидаю, что более новая разработка уже нацелена на него и тамэто встроенное решение.Есть ли новости на эту тему за последние пять лет?

1 Ответ

0 голосов
/ 04 марта 2019

Просто взглянул на GraphicImageRenderer , желающий выяснить, как они генерируют этот динамический URL.Они используют статический метод в своих 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 компонента, а затем получу URI от этого компонента, который воспроизводит поведение средства визуализации, показанного выше:

Код 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>

И мой бин aka 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:

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:

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()} не затронут.

Возвращаясь к вашему вопросу: нет новостей.Динамический URI создается и напрямую отправляется в браузер при рендеринге.Компонент GraphicImage не предоставляет для этого никакого метода получения.То, что я представил здесь, представляет собой вариант обхода на стороне сервера без необходимости создания нового сервлета.

Редактировать:

Конечно, вы также можете параметризовать getImageUri метод и привязать ваш компонент Image к некоторой произвольной переменной, которая приблизит вас к вашей демонстрации var="..." пример:

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

Затем используйте этот метод:

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

ThisТаким образом, нет необходимости создавать бин или метод для каждого изображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...