2013-02-17 14 views
5

Ten problem dotyczy bazy danych Oracle 10g. Ten sam kod działa dobrze z bazą danych MySQL.Błąd podczas próby wyświetlenia obrazu (obiekt blob) w jsp (Spring i Hibernate with Oracle Database)

moim modelu klasy

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

Ta metoda z mojej klasy kontrolera, który pomaga utrzymać obiekt blob do klasy modelu.

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

Jest to kolejna metoda z klasy kontrolera, gdzie staram się czytać Obiekt 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; 
    } 

gdy próbuję wywołać określony obraz ten jest wyjście otrzymuję

error message i am gettting

Po uruchomieniu adresu URL z przeglądarki http://localhost:7070/KillerLinks/image/381.htm

ten jest wyświetlany błąd w moim konsoli

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

Proszę mi pomóc rozwiązać ten problem. Chcę, aby obraz był wyświetlany. Z góry dzięki.

+0

Zmień @Lob na @ Blob – Kris

+0

@kris @ Blob jest niedostępny. powinienem dodać do tego jakieś słoiki. – SKR

+0

Chwileczkę. Wrócę, nie zmienia się na @Blob – Kris

Odpowiedz

1

myślę kontroler powinien wyglądać następująco:

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

To będzie wysłać plik do bezpośredniego pobrania.

Dodatkowo można dodać plik obrazu do strony html

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

kod, który podałeś, nie działa. Kiedy użyłem tego kodu, pobiera on obraz z 0 bajtów. – SKR

1

Spróbuj

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

} 
+0

Próbowałem Twojego kodu, ale otrzymałem pustą stronę. Brak danych wyjściowych, nawet błąd (tylko pusta strona). – SKR

+0

jeśli nie chcesz pobierać, usuń ten kod - response.setHeader ("Content-Disposition", "inline; filename = \" "+ linkform.getTittle() +" \ ""); Zobacz zaktualizowaną odpowiedź, używam podobnego kodu do wyświetlania obrazu w jsp – Kris

+0

usunąłem tę linię, ale wciąż tak samo. Brak danych wyjściowych, nawet błąd (tylko pusta strona). – SKR

1

Czy istnieje jakiś inny fragment kodu powołuje linkform.getFileData()? Jeśli nie, czy nie, modyfikujesz swój kod trochę jak po. Entity Class:

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

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

A także zmienić kontroler oparty na nowej getFileData().

Nie mogę zagwarantować, że to rozwiązanie zdecydowanie rozwiąże twój probleam, ale warto dać mu szansę. Powodem, dla którego mówię, jest to, że śledzenie wyjątków mówi, że kod nie powiódł się podczas otwierania połączenia DB w celu załadowania danych Blob. I zgodnie z dokumentem java, Interfejs Blob jest właściwie logicznym wskaźnikiem do bazowego SQL-a, a nie do przechowywania prawdziwych danych. Ponieważ kontroler jest poza sesją hibernacji, może nie być w stanie otworzyć innego połączenia z bazą danych w celu pobrania wartości Bloba.

Powiązane problemy