Siva Kumar Reddy G
Siva Kumar Reddy G

Reputation: 1274

Getting error while trying to display image(blob object) in jsp (Spring and Hibernate with Oracle Database)

This problem is with oracle 10g database. Same code is working fine with MySQL Database.

My Model Class

package com.killerlinks.model;

    import java.io.Serializable;
    import java.sql.Blob;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Lob;
    import javax.persistence.Table;

    @Entity
    @Table(name="links")
    public class Linkform implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Column(name="id")
        private Long id;
        @Column(name="tittle")
        private String tittle;
        @Column(name="xdesc")
        private String desc;
        @Column(name="url")
        private String url;
        @Column(name="category")
        private String category;
        @Column(name="xdate")
        private String date;
        @Column(name="xtime")
        private String time;
        @Column(name="tags")
        private String tags;

        @Column(name="image")
        @Lob
        private Blob fileData;

        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getTittle() {
            return tittle;
        }
        public void setTittle(String tittle) {
            this.tittle = tittle;
        }
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        public String getUrl() {
            return url;
        }
        public void setUrl(String url) {
            this.url = url;
        }
        public String getCategory() {
            return category;
        }
        public void setCategory(String category) {
            this.category = category;
        }
        public String getDate() {
            return date;
        }
        public void setDate(String date) {
            this.date = date;
        }
        public String getTime() {
            return time;
        }
        public void setTime(String time) {
            this.time = time;
        }
        public String getTags() {
            return tags;
        }
        public void setTags(String tags) {
            this.tags = tags;
        }

        @Override
        public String toString()
        { 
            return "Linkform [tittle=" + tittle + ", url=" + url + ", category="+ category +", tags="+ tags +", desc="+ desc +", fileData="+fileData+" ]";
        }
        public Blob getFileData() {
            return fileData;
        }
        public void setFileData(Blob fileData) {
            this.fileData = fileData;
        }
    }

This method from my controller class which helps to keep blob object to model class.

private Linkform preparingModelBean(LinkformBean linkformbean, MultipartFile file)
    {
        Linkform linkform = new Linkform();
        linkform.setTittle(linkformbean.getTittle());
        linkform.setUrl(linkformbean.getUrl());
        linkform.setCategory(linkformbean.getCategory());
        linkform.setDesc(linkformbean.getDesc());
        linkform.setTags(linkformbean.getTags());


        Date date = new Date();
        SimpleDateFormat sdate = new SimpleDateFormat("yyyy.MM.dd");
        SimpleDateFormat stime = new SimpleDateFormat("HH:mm");


        linkform.setDate(sdate.format(date));
        linkform.setTime(stime.format(date));

        try {
            Blob blob = Hibernate.createBlob(file.getInputStream());

            linkform.setFileData(blob);

        } catch (IOException e) {
            e.printStackTrace();
        }


        return linkform;
    }

This is another method from controller class, where i am trying to read blob object

@RequestMapping(value ="/image/{id}")
    public String image(@PathVariable("id")Long id, HttpServletResponse response)
    {
        Linkform linkform = linkformservice.getALink(id);

        try {
            response.setHeader("Content-Disposition", "inline;filename=\"" +linkform.getTittle()+ "\"");
            OutputStream out = response.getOutputStream();
            response.setContentType("image/jpeg");
            IOUtils.copy(linkform.getFileData().getBinaryStream(), out);
            out.flush();
            out.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

when i am trying to call specific image this is output i am getting

error message i am gettting

When i trigger the url from the browser http://localhost:7070/KillerLinks/image/381.htm

this is the error displayed in my console

java.sql.SQLException: Closed Connection
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
    at oracle.sql.BLOB.getDBAccess(BLOB.java:955)
    at oracle.sql.BLOB.getBinaryStream(BLOB.java:229)
    at org.hibernate.lob.SerializableBlob.getBinaryStream(SerializableBlob.java:39)
    at com.killerlinks.controllers.CategoryController.image(CategoryController.java:63)
    at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
java.sql.SQLException: Closed Connection
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
    at oracle.sql.BLOB.getDBAccess(BLOB.java:955)
    at oracle.sql.BLOB.getBinaryStream(BLOB.java:229)
    at org.hibernate.lob.SerializableBlob.getBinaryStream(SerializableBlob.java:39)
    at com.killerlinks.controllers.CategoryController.image(CategoryController.java:77)
    at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)
Hibernate: select linkform0_.id as id1_0_, linkform0_.category as category1_0_, linkform0_.xdate as xdate1_0_, linkform0_.xdesc as xdesc1_0_, linkform0_.image as image1_0_, linkform0_.tags as tags1_0_, linkform0_.xtime as xtime1_0_, linkform0_.tittle as tittle1_0_, linkform0_.url as url1_0_, linkform0_.xviews as xviews1_0_ from links linkform0_ where linkform0_.id=?

Please help me to fix the bug. I want image to be displayed. Thanks in advance.

Upvotes: 5

Views: 2615

Answers (3)

spiritwalker
spiritwalker

Reputation: 2257

Is there any other piece of code invoking linkform.getFileData()? If not, do you mind modifying your code a little bit like following. Entity Class:

@Column(name="image")
@Lob
private Byte[] fileData;

public Byte[] getFileData() {
    return fileData;
}
public void setFileData(Byte[] fileData) {
     this.fileData = fileData;
}

And also change your controller based on new getFileData().

I cannot guarantee that this solution would definitely solve your probleam, but it is worth giving it a go. The reason I am saying so is that the exception trace tells you code failed on opening an DB connection to load Blob data. And according to java doc, the Interface Blob is actually a logical pointer to underlying SQL Blob rather than holding real data. Since controller is out of hibernate session, it might not be able to open another connection to DB for retrieving Blob value.

Upvotes: 1

Kris
Kris

Reputation: 1902

Try this

    @RequestMapping(value ="/image/{id}")
public void image(@PathVariable("id")Long id, HttpServletResponse response)
{
    Linkform linkform = linkformservice.getALink(id);
    InputStream image = null;
    image = linkform.getFileData().getBinaryStream();

    try {
        OutputStream out = response.getOutputStream();
        response.setContentType("image/jpeg");

        int length = (int) image.available();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        while ((length = image.read(buffer)) != -1) {
            out.write(buffer, 0, length);
        }
           response.flushBuffer();
        //image.close();
        out.flush();
        out.close();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }

}

Upvotes: 1

danny.lesnik
danny.lesnik

Reputation: 18639

I think your controller should look like this:

@RequestMapping(value ="/image/{id}")
    public void image(@PathVariable("id")Long id, HttpServletResponse response)
    {
        Linkform linkform = linkformservice.getALink(id);

        try {
            response.setContentType("application/x-download");
            response.setHeader("Content-Disposition", "attachment; filename=" + filename);

            OutputStream out = response.getOutputStream();
            response.setContentType("image/jpeg");
            IOUtils.copy(linkform.getFileData().getBinaryStream(), out);
            out.flush();
            out.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

It will send your file to direct download.

In addition you can add image file to html page

<img src="/image/5"></img>

Upvotes: 1

Related Questions