1

Trying to get a blob and make it into a streamed content. I get the bytes, they do get converted into ByteArrayInputStream and I am returning the StremedContent image, but i keep getting this:

    SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/ConfigEmployee] threw exception
    java.io.IOException: java.lang.NullPointerException
Caused by: java.lang.NullPointerException
    at org.primefaces.application.resource.StreamedContentHandler.handle(StreamedContentHandler.java:56)
    ... 21 more

line 56 has this: externalContext.setResponseContentType(streamedContent.getContentType());

I need to add that the streamed content is returned two times per Image object.

Image bean:

public Image(byte[] bytes,String name)
    {
        this.id=new MyDatabase().getLastId("image")+1;
        this.name=name;
        this.byteData=bytes;

        InputStream is=new ByteArrayInputStream(bytes);
        this.image = new DefaultStreamedContent(is,"image/png");

    }
public StreamedContent getImage() 
    {
        return image;
    }

HTML code

<div class="dataTable">
            <h:form id="imageList">
                <p:dataTable var="img" value="#{imageView.images}" rowKey="#{img.id}" rows="10" lazy="true" paginator="true">
                    <p:column headerText="Image">
                        <p:graphicImage style="width:80px; height:80px" value="#{img.image}" />
                    </p:column>
                    <p:column width="200" headerText="Name">
                        <h:outputText value="#{img.name}" />
                    </p:column>
                    <p:column width="200" headerText="Edit">
                        <h:commandButton value="Enter" actionListener="#{imageView.convertImage(img)}" action="Image?faces-redirect=true" />
                    </p:column>
                </p:dataTable>


            </h:form>
        </div>

Lazy load

@Override
    public List<Image> load(int first, int pageSize, String sortField, SortOrder sortOrder,
            Map<String, Object> filters)
    {
        db.openDatabase();
        ResultSet rs = db.getImage();

        List<Image> imgList = new ArrayList<Image>();

        try
        {
            if (rs.last())
                this.setRowCount(rs.getRow());

            for (rs.absolute(first); rs.next() && first <= (first + pageSize); first++)
            {
                imgList.add(new Image(rs.getBytes("byteData"), rs.getString("name")));

            }
        }
        catch (SQLException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
            db.closeDatabase();
        }
        return imgList;
    }

Primefaces 5.1, JSF 2.2, Tomcat v7.0

FancyPants
  • 93
  • 4
  • 20

1 Answers1

1

What is the scope of the bean, it should be View or Session scoped, and you will have to change the way you access your bean. For the dynamically created images, two requests are being sent. One to render the HTML, that renders the img tag. Than the second, fired based on the src attribute. The model must retain the values accross the subsequent requests.

all explained beautifully here Display dynamic image from database with p:graphicImage and StreamedContent

Community
  • 1
  • 1
Master Slave
  • 24,735
  • 4
  • 53
  • 54
  • Thank you, I did found this previously, but due to the date I thought of it as outdated. I would like to ask the `StudentService` class, what is it for and what does it do? – FancyPants Nov 21 '14 at 15:13
  • StudentService is an exemplary class, the concept is important. The bean in the example is marked as application scope, so there exist only a single instance. If you were to mark your ImageBean as application scope, you would solve your problem, but if the two users visit your page they would all see the same image, as it would be loaded once and not per-request. For this reason, a unique param is added in the p:graphicImage (you have id param as well), and the param is take within the getImage from the request context.This way, the bean persists accross request, and serves images per request – Master Slave Nov 21 '14 at 15:29
  • It works(half way), in the html code i gave it shows either a blank square or a image icon (the one you get when there is no image). But since I have a lot of images which you can select by clicking the button, it sends to the other page with the image there, but if i want to go back and choose another one, when the page redirects me it still shows the old image, so i need to refresh the page to show the new image. It's like the page loads faster than the image is being generated, but i guess its another problem. – FancyPants Nov 21 '14 at 15:51