[OutputStream] Lidando com imagens

5 respostas
_fs

Olá, boa tarde.

Ambiente: tomcat 5.0.14, servlets, win2000 server, sqlserver2000

Objetivo: mostrar uma imagem guardada em um banco de dados numa página html

O que eu consegui até agora: após algumas boas horas de pesquisa, descobri que um simples out.print apontando para uma página com content setado para image/gif bastaria para fazer o que preciso.
Pego a imagem do banco de dados (byte) e tento fazer um OutputStram( byte[] ).

[b]Então, qual o maldito problema?[b]
Eu recebo esta linda e gigantesca exceção:

ClientAbortException:  java.net.SocketException: Connection reset by peer: socke
t write error
        at org.apache.coyote.tomcat5.OutputBuffer.realWriteBytes(OutputBuffer.ja
va:410)
        at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:428)
        at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:300)
        at org.apache.coyote.tomcat5.OutputBuffer.writeByte(OutputBuffer.java:46
4)
        at org.apache.coyote.tomcat5.CoyoteOutputStream.write(CoyoteOutputStream
.java:96)
        at getlink.selectmanager.utils.ImageDisplay.doGet(ImageDisplay.java:47)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:284)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:204)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
alve.java:256)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(Standard
ContextValve.java:245)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:199)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:195)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:164)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:149)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:156)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)

        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:20
9)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:781)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
ssConnection(Http11Protocol.java:549)
        at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java
:589)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
ool.java:666)
        at java.lang.Thread.run(Thread.java:536)
ClientAbortException:  java.net.SocketException: Connection reset by peer: socke
t write error
        at org.apache.coyote.tomcat5.OutputBuffer.realWriteBytes(OutputBuffer.ja
va:410)
        at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:428)
        at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:300)
        at org.apache.coyote.tomcat5.OutputBuffer.writeByte(OutputBuffer.java:46
4)
        at org.apache.coyote.tomcat5.CoyoteOutputStream.write(CoyoteOutputStream
.java:96)
        at getlink.selectmanager.utils.ImageDisplay.doGet(ImageDisplay.java:47)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:743)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:284)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:204)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
alve.java:256)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardContextValve.invokeInternal(Standard
ContextValve.java:245)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:199)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:195)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:164)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:149)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:156)
        at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValv
eContext.java:151)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:563)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)

        at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:20
9)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:781)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
ssConnection(Http11Protocol.java:549)
        at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java
:589)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
ool.java:666)
        at java.lang.Thread.run(Thread.java:536)

Eu pesquisei um pouco sobre este erro e acho que ele é causado pelo excesso de bytes sendo transmitidos de uma só vez. É isso mesmo?

Bem, alguém pode me dar uma luz para resolver isso?

Muitérrimo obrigado :*

5 Respostas

_fs

Bom, só para adicionar, isto aqui funciona normalmente (com o mimetype setado corretamente):

File f = new File( "d:\lipe\imagens\necro\necro4.jpg" );
			BufferedImage bi = ImageIO.read( f );
			ImageIO.write( bi, "jpg", out );

Mas como eu faço sendo que só recebo bytes da database?

louds

Escreve o byte[] no OutputStream ue.

_fs

Assim dá o erro que eu mencionei no primeiro tópico louds … e não tenho a menor idéia do que causa isso :frowning:

N

Cara tenho uma aplicação rodando com o mesmo ambiente que o seu, porém o datatype do campo no SQL é Image e não Text, percebi que há uma grande diferença ao enviar quando armazeno MP3 mas imagem nunca verifiquei, dá uma olhada no trecho do código vê se te ajuda:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
   
    ServletOutputStream out = response.getOutputStream();

    Connection conn = null;
    Statement stmt = null;
    ResultSet dsImage = null;
    InputStream      fImage  = null;
    JPEGImageEncoder encoder = null;

    response.setContentType("image/jpeg");
    String sSQL = "SELECT IMG_IMAGEM FROM IMAGEM WHERE IMG_ID = " + request.getParameter("img_id"); 

    try {
        // Get a DB connection from the Broker

        conn = myBroker.getConnection();            

        stmt = conn.createStatement();

        dsImage = stmt.executeQuery(sSQL);  
        
        if (dsImage.next())
          fImage = dsImage.getBinaryStream(1);
        else
          fImage = getServletContext().getResourceAsStream("/img/sem_imagem.jpg");

        try {
          encoder = JPEGCodec.createJPEGEncoder(out);
          encoder.encode(JPEGCodec.createJPEGDecoder( fImage ).decodeAsBufferedImage());
        } catch ( Exception ex ) {
          encoder = JPEGCodec.createJPEGEncoder(out);
          encoder.encode(JPEGCodec.createJPEGDecoder( getServletContext().getResourceAsStream("/img/sem_imagem.jpg") ).decodeAsBufferedImage());
        }

        fImage.close();
        out.close();

    } catch (SQLException e1) {
        out.println("<i><b>Error code:</b> " + e1 + "</i>");
} finally {
        try{if(fImage != null) {fImage.close();}} catch(Exception ex){};
        
        try{if(encoder != null) {encoder = null;}} catch(Exception ex){};

        try{if(dsImage != null) {dsImage.close();}} catch(SQLException e1){};

        try{if(stmt != null) {stmt.close();}} catch(SQLException e1){};
        
        // The connection is returned to the Broker
        myBroker.freeConnection(conn);
 }
    
    out.close();
    response.getOutputStream().close();

}
_fs

numsay, muitíssimo obrigado pelo exemplo, será bastante útil.

Mas ontem a noite resolvi ler o help do sqlserver2000 e percebi que o problema vai um pouco mais além. A informação sobre imagem que ele guarda no registro não são os bytes da imagem, mas sim um endereço de memória para onde os bytes estão realmente guardados no banco (em pacotinhos de 4kb). O que preciso antes de fazer o que me falou é descobrir como pegar os bytes realmente :smiley:

Novamente, muito obrigado \o/

dica: quando for postar código no fórum, coloque assim [ code]seucodigo[ /code], assim ele fica endentado :smiley:

Criado 1 de março de 2004
Ultima resposta 2 de mar. de 2004
Respostas 5
Participantes 3