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

特定の画像を呼び出そうとすると、これが出力されます

エラーメッセージが表示されます

ブラウザからURLをトリガーするとhttp://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

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.

于 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 に答える