Search code examples
jsfjsf-2primefaces

org.primefaces.model.DefaultStreamedContent cannot be cast to java.lang.String


I am trying to display an image which is stored in a BLOB in a MySQL, with OpenJpa for persistence. I'm using a <p:graphicImage> where by the user's profile picture, but I get an error when opening the page.

This is the code of the page where the photo is loaded.

<h:panelGrid columns="2">
      <p:graphicImage value="#{login.getImage()}" alt="/sistema.ciclos.calidad/resources/perfil/default.png"  width="150px" height="150px">
           <f:param name="id" value="#{param.id}" />
      </p:graphicImage>
      <h:panelGrid columns="1">
           <h:outputLabel  id="nombre" value="#{login.usuario.getNombreCompleto()}"></h:outputLabel>
           <h:outputLabel id="cargo" value="#{login.usuario.cargo.cargo}"></h:outputLabel>
           <h:outputLabel  id="correo" value="#{login.usuario.correo}"></h:outputLabel>
      </h:panelGrid>
</h:panelGrid>

this method returns me the photo, in the bean.

        @ManagedProperty("#{param.id}")
        private Long id;

        @PostConstruct
        public void init()  {
            ...
            id=usuario.getIdUsuario();
        }

        ...

        public StreamedContent  getImage() {
            byte[] bytes=usuario.getFotoPerfil();
            return new DefaultStreamedContent(new ByteArrayInputStream(bytes));
        }

I'm using Primefaces 4.0, Jsf 2.0, maven. I tried what is in this post (Post), but not happening

javax.servlet.ServletException: org.primefaces.model.DefaultStreamedContent cannot be cast to java.lang.String
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:325)
        org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98)
        cl.im.ciclos.service.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:32)
        cl.im.ciclos.service.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:32)
        cl.im.ciclos.service.security.LoginFilter.doFilter(LoginFilter.java:52)
    root cause

    java.lang.ClassCastException: org.primefaces.model.DefaultStreamedContent cannot be cast to java.lang.String
        com.sun.faces.renderkit.RenderKitUtils.getImageSource(RenderKitUtils.java:1282)
        com.sun.faces.renderkit.html_basic.ImageRenderer.encodeEnd(ImageRenderer.java:97)
        javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
        com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:295)
        com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
        com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
        javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
        javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
        javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
        javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
        com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
        com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
        javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
        com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
        com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
        org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98)
        cl.im.ciclos.service.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:32)
        cl.im.ciclos.service.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:32)
        cl.im.ciclos.service.security.LoginFilter.doFilter(LoginFilter.java:52)

Solution

  • This line from the stack trace

    com.sun.faces.renderkit.html_basic.ImageRenderer.encodeEnd(ImageRenderer.java:97)
    

    tells that you're actually using <h:graphicImage>, not <p:graphicImage>. The former indeed doesn't support DefaultStreamedContent, which totally explains this problem. You should be changing the <h:graphicImage> to <p:graphicImage> in order to be able to use DefaultStreamedContent.

    So, either you're not running the code you think you're running (perhaps you edited h: to p:, but somehow forgot or failed to rebuild/redeploy/restart), or you're looking at the wrong place in your XHTML source code in an attempt to naildown the cause. This exception is at least not caused by anything in the XHTML source code posted so far in your question.

    If you were actually using <p:graphicImage>, then the org.primefaces.component.graphicimage.GraphicImageRenderer class would have appeared at this place in the stack trace instead. If this is even not true, then the xmlns:p="..." declaration in your XML file is most probably not properly set to http://primefaces.org/ui. This way basically the whole tag is unseen and JSF is then trying to print the value as template text.