5

这个问题与 oracle 10g 数据库有关。相同的代码适用于 MySQL 数据库。

我的模特班

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;
        }
    }

这个方法来自我的控制器类,它有助于将 blob 对象保存到模型类。

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;
    }

这是控制器类的另一种方法,我正在尝试读取 blob 对象

@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;
    }

当我试图调用特定图像时,这是我得到的输出

错误信息我得到

当我从浏览器触发 urlhttp://localhost:7070/KillerLinks/image/381.htm

这是我的控制台中显示的错误

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=?

请帮我修复错误。我想显示图像。提前致谢。

4

3 回答 3

1

尝试这个

    @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();
    }

}
于 2013-02-21T05:18:51.727 回答
1

是否有任何其他代码调用linkform.getFileData()?如果没有,您介意修改您的代码,如下所示。实体类:

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

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

并根据新的getFileData()更改您的控制器。

我不能保证这个解决方案一定能解决你的问题,但值得一试。我这么说的原因是异常跟踪告诉您代码在打开数据库连接以加载 Blob 数据时失败。根据java doc,Interface Blob实际上是一个指向底层SQL Blob的逻辑指针,而不是保存真实数据。由于控制器不在休眠会话中,它可能无法打开另一个到 DB 的连接来检索 Blob 值。

于 2013-02-24T09:54:23.237 回答
1

我认为您的控制器应如下所示:

@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();
        }
    }

它会将您的文件发送到直接下载。

此外,您可以将图像文件添加到 html 页面

<img src="/image/5"></img>
于 2013-02-17T21:41:50.960 回答