Wyświetlanie obrazów blob bazy danych w środku
Używam PrimeFaces 3.2 na JBoss 7.1.1.
Próbuję wyświetlić obraz, który jest przechowywany w BLOBIE w bazie danych MySQL w <ui:repeat>
. Obraz jest przechowywany w byte[]
, a następnie konwertowany na StreamedContent
w następujący sposób:
InputStream stream = new ByteArrayInputStream(ingredient.getImage());
ingredient.setJsfImage(new DefaultStreamedContent(stream, "image/jpg"));
Następnie staram się wyświetlić go w Fasetce w następujący sposób:
<ui:repeat var="ingredient" value="#{formBean.ingredientResultSet}">
<p:panel id="resultsPanel" header="#{ingredient.location.shopName}">
<p:graphicImage value="#{ingredient.jsfImage}" alt="No picture set" />
...
Jednak podczas ładowania strony w JBoss pojawia się następujący błąd:
Ciężkie [org.primefaces.podanie.PrimeResourceHandler] (http--127.0.0.1-8080-12) błąd w streaming dynamic resource.
Jak to jest spowodowane i jak Mogę to rozwiązać?
6 answers
Musisz zdać sobie sprawę, że <p:graphicImage>
faktycznie renderuje <img src>
element tylko z adresem URL, który jest później indywidualnie wywoływany przez webbrowser, gdy ma analizować uzyskane znaczniki HTML i prezentować wyniki.
Więc cokolwiek robisz w metodzie getter <p:graphicImage>
musi być zaprojektowane w taki sposób, że może być wywoływane na zasadzie każdego żądania. Tak więc, najbardziej rozsądnym podejściem byłoby stworzenie <p:graphicImage>
z <f:param>
, w którym <p:graphicImage value>
wskazuje całkowicie samodzielne żądanie lub aplikacja scoped bean i <f:param value>
wskazuje unikalny identyfikator obrazu.
Np.
<p:graphicImage value="#{images.image}">
<f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>
Gdzie Images
może wyglądać tak:
@ManagedBean
@ApplicationScoped
public class Images {
@EJB
private ImageService service;
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Return a real StreamedContent with the image bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Image image = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
}
}
}
Jeśli używasz już OmniFaces 2.0 lub nowszego, rozważ użycie jego <o:graphicImage>
zamiast tego, które mogą być używane bardziej intuicyjnie, prawie wykonalnie tak, jak się spodziewałeś. Zobacz również blog na ten temat.
Zobacz też:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:27
Nie rozumiem, po co ci to. Możesz po prostu utworzyć servlet, który pobierze obraz z bazy danych z mapowaniem " / images / yourimage.jpg".
Oto krótki samouczek z odpowiednim kodem, jak to zrobić.
JSF-wyświetlanie obrazów z bazy danych w JSF
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-17 14:10:03
Dzięki BalusC. Zrobiłem to, definiując liczbę całkowitą w backing bean i przypisując jej różną wartość podczas aktualizacji ByteArray dla obrazu. Ta liczba całkowita służy jako unikalny identyfikator obrazu. Następnie ustawiam tę liczbę całkowitą jako wartość <f:param>
wewnątrz <p:graphicImage>
na stronie.
Znacznik obrazu wygląda jak
<p:graphicImage value="#{empBean.image}">
<f:param name="id" value="#{empBean.imageId}" />
</p:graphicImage>`
I ustawienie obrazu w backing bean jako
if(user.getPicture()!=null){
imageId = (int) new Date().getTime();
BinaryStreamImpl bs = new BinaryStreamImpl(user.getPicture());
//picture is byte[] property in user class
this.image = new DefaultStreamedContent(bs.getInputStream(), "image/png");
}
Teraz działa dobrze.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 13:00:49
Należy pamiętać, do czego komponent graphicImage
renderuje na stronie. Renderuje do elementu HTML <img>
. W przeglądarce żądanie zostanie złożone dla strony JSF, a następnie kolejne żądania pojawią się również dla każdego z obrazów na stronie.
Te obrazy pochodzą z servletu zasobów PrimeFaces, a nie FacesServlet, co oznacza, że zakres zarządzanej fasoli i jej właściwości prawdopodobnie nie mają zastosowania.
Spróbuj najpierw załadować obiekt blob do tablicy bajtów wtedy to prawdopodobnie zacznie działać.
EDIT: zobacz moją następującą odpowiedź na to podobne pytanie. graphicimage nie renderuje streamedcontent w Primefaces
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:33
InputStream is = new ByteArrayInputStream((byte[]) yourBlobData);
myImage = new DefaultStreamedContent(is, "image/png");
Na stronie jsf;
<p:graphicImage value="#{controller.myImage}" style="width:200px;width:500px" />
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-19 09:15:22
Mmm na 99% jestem pewien, że <p:graphicImage
nie działa z ui: powtórz, że będziesz miał z tym wiele problemów (bo zrobiłem XD), polecam Ci stworzyć servlet i podawać obrazy jako strumień wejściowy(jest tam wiele przykładów).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-14 18:53:54