Recuperar Imagem campo BLOB e exibir numa JSP

Tenho uma tabela foto, que têm um campo BLOB e a foto está gravada nesse campo, preciso recuperar essa foto e exibir numa JSP. Estou tendo erro e não sei se estou indo pelo caminho certo.
Estou tentando assim:

utputStream out = response.getOutputStream(); 
		
int tamanho = 1;
byte[] buffer = new byte[1024*tamanho];
InputStream is = getDao().recuperaFoto();
int bytesread = 0;
while((bytesread = is.read(buffer))!=-1){
    out.write(buffer,0,bytesread);
}
out.flush();
out.close();
is.close();

Faça com que o src da sua tag img seja o nome do seu servlet que retornará a imagem do banco.


<img name="nomeImagem" src="servletImagem" border="0">

Juliano, uma pergunta eu preciso setar lá no request do meu Servlet um atributo com o nome do meu servlet para ele conseguir?

Lá no servlet faça o seguinte, no método service, recupere a sua imagem do banco e crie uma estrutura de buffer de imagem:


...
...
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");

ServletOutputStream out = response.getOutputStream()	;
ImageIO.write(<sua imagem>, "jpeg", response.getOutputStream());
out.flush();
out.close();

Não esqueça de no arquivo web.xml colocar o mapping e a declaração desse servlet.

Se você usa banco Oracle, tem esse tópico que criei para auxiliar com campos blob: http://www.guj.com.br/posts/list/42508.java

Olha só segue meu servlet:

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setHeader("Cache-Control", "no-store");
		response.setHeader("Pragma", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		 
		ServletOutputStream out = response.getOutputStream();
		BufferedImage buffer = ImageIO.read(getDao().recuperaFoto());
		ImageIO.write(buffer, "jpeg", response.getOutputStream());
		out.flush();
		out.close();
		
 		RequestDispatcher rd = request.getRequestDispatcher("exibe.jsp");
 	    rd.forward(request,response);
	}

Agora segue o meu método recuperaFoto():

	public InputStream recuperaFoto(){
		String sql = "select foto from foto where id_foto = ?";
		Connection con = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		InputStream in = null;
		
		try {
			con = getConnection();
			pst = con.prepareStatement(sql);
			pst.setLong(1, 3);
			rs = pst.executeQuery();
			
			while(rs.next()){
				Blob blob = rs.getBlob("foto");
				in = blob.getBinaryStream();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try{rs.close();}catch(Exception e){}
			try{pst.close();}catch(Exception e){}
			try{con.close();}catch(Exception e){}
		}
		return in;
	}

E olha só estou tendo o seguinte erro:

java.lang.NullPointerException
at oracle.sql.LobPlsqlUtil.plsql_read(LobPlsqlUtil.java:969)
at oracle.sql.LobPlsqlUtil.plsql_read(LobPlsqlUtil.java:63)
at oracle.jdbc.dbaccess.DBAccess.lobRead(DBAccess.java:662)
at oracle.sql.LobDBAccessImpl.getBytes(LobDBAccessImpl.java:100)
at oracle.sql.BLOB.getBytes(BLOB.java:214)
at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:162)
at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:108)
at javax.imageio.stream.FileCacheImageInputStream.readUntil(FileCacheImageInputStream.java:98)
at javax.imageio.stream.FileCacheImageInputStream.read(FileCacheImageInputStream.java:117)
at com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi.canDecodeInput(JPEGImageReaderSpi.java:78)
at javax.imageio.ImageIO$CanDecodeInputFilter.filter(ImageIO.java:526)
at javax.imageio.spi.FilterIterator.advance(ServiceRegistry.java:789)
at javax.imageio.spi.FilterIterator.(ServiceRegistry.java:783)
at javax.imageio.spi.ServiceRegistry.getServiceProviders(ServiceRegistry.java:490)
at javax.imageio.ImageIO.getImageReaders(ImageIO.java:605)
at javax.imageio.ImageIO.read(ImageIO.java:1376)
at javax.imageio.ImageIO.read(ImageIO.java:1306)
at servlet.FotoServlet.doPost(FotoServlet.java:97)

Você não precisa fazer o

por que esse servlet “todo” será a foto que será exibida lá na tag

Quando ao NullPointerException acho que a sua imagem é nula. Dê uma depurada aí pra ver o que está acontecendo.

Faça assim cria um Servlet e no metodo doGet()
Como e um campo Blob vc escreve em um array de bytes


  ResultSet rs = stmt.executeQuery("select capa from livros where livro_id = 1");
            InputStream leitura;
            ByteArrayOutputStream buffer = new ByteArrayOutputStream(1024);
            if (rs.next()) 
           {
                leitura = rs.getBinaryStream(1);
                int lido = 0;
                lido = leitura.read();
                while (lido != -1) {
                    buffer.write(lido);
                    lido = leitura.read();
                }
            }
            
            // converte buffer em array de bytes e envia para cliente
            response.getOutputStream().write(buffer.toByteArray());
        
            // encerrar recursos
            rs.close();
            stmt.close();
            con.close();

No seu HTML


[img src=SeuServlet?idImagem=?]

Olha só consegui gravar a imagem no banco e consegui exibir na minha JSP, mais só exibe a imagem o resto do meu código HTML ele não exibe.

Segue Servlet:

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
		response.setContentType("image/jpeg");		
		ServletOutputStream out = response.getOutputStream(); 
		
		int tamanho = 1;
		byte[] buffer = new byte[1024*tamanho];
		InputStream is = recuperaFoto();
		int bytesread = 0;
		while((bytesread = is.read(buffer))!=-1){
			out.write(buffer,0,bytesread);
		}
		out.flush();
		out.close();
		is.close();
	}

Agora segue o código que está na JSP:

<html>
    <head>
       <title>Exibe Foto cadastrada no Banco número 1</title>
    </head>
    <body>
       <form name="form1" method="post">
<table width="750" border="1">
  <tr>
    <td>Nome:</td>
    <td>&nbsp;</td>
    <td rowspan="3"><img style="width:30px;height:30px;" name="img1" src="GeraFoto1"></td>
  </tr>
  <tr>
    <td>Telefone:</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td>Empresa:</td>
    <td>&nbsp;</td>
  </tr>
  <tr>
    <td colspan="3">OBS: Funcion&aacute;ria que trabalha na recep&ccedil;&atilde;o. </td>
  </tr>
</table>
       </form>
    </body>
 </html>

Segue um exemplo que rodou aqui:


public class Imagem extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession ses = request.getSession();

        Connection conn = null;
        PreparedStatement pstmt = null;
        Blob mapBlob = null;
        String contentType = "";
        String nomArquivo = "";
		
        try {
    	Class.forName("oracle.jdbc.driver.OracleDriver");				
    	conn = DriverManager.getConnection("jdbc:oracle:thin:@<host>:1521:<banco>", "<conta>", "<senha>");
	conn.setAutoCommit(false);
    	
	String cdArquivo = "1";
	        
	pstmt = conn.prepareStatement("select bl_arquivo from testeblob where cd_arquivo = ?");
	pstmt.setInt(1,Integer.parseInt(cdArquivo));
	ResultSet res = pstmt.executeQuery();
		
	if (res.next()) {
	   mapBlob = res.getBlob("BL_ARQUIVO");
	}			
	res.getStatement().close();
	byte[] arquivo = mapBlob.getBytes(1,(new Long(mapBlob.length())).intValue());

	response.setHeader("Cache-Control", "no-store");
	response.setHeader("Pragma", "no-cache");
	response.setDateHeader("Expires", 0);
	response.setContentType("image/jpeg");

	ServletOutputStream out = response.getOutputStream();
	out.write(arquivo);
	out.flush();
	out.close();
	        
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
        	try {
        	if (conn != null) 
        	conn.close();
        	}
        	catch (Exception e) {
        	}
        }
    }
}

Basta fazer lá no jsp:


<img src="imagem">

No web.xml:


    <servlet>
        <servlet-name>imagem</servlet-name>
        <servlet-class>Imagem</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>imagem</servlet-name>
        <url-pattern>/imagem</url-pattern>
    </servlet-mapping>

Julianostr olha só o código que eu mostrei ele está funcionando a imagem está sendo recuperado do banco e está sendo exibido na tela, o meu problema é o seguinte eu tenho algunas valores no meu html que somem e fica só a imagem.

Você já viu o código fonte da página gerada pra ver até onde ele montou pra saber em que trecho ocorreu o erro?

Veja que a sua imagem tem que ser um servlet a parte, com somente o método service nele.

Galera, consegui gerar do jeito que tava precisando, consigo manipular o tamanho da imagem agora. Obrigado, pela ajuda.

Ola,

Estou tentanto exibir um pdf de campo Blob

Salvei uma imagem para utilizar o teste enviado por “julianostr” mas não funcionou.

E o pior nao deu erro no console. Abriu a pagina com a imagem quebrada. O que aconteceu?

Amigo você já conseguiu resolver esse problema!

Fala pessoal…de muita ajuda este topico…

porem, tenho um pequeno problema…

estou fazendo uma especie de vitrine de produtos…ao pedir pra exibir todos os produtos, ele lista numa tabela o jsp, todos os produtos que necessito…porem, na imagem, ocorre o erro…somente está exibindo a primeira imagem no banco…ou seja, todas as tuplas exibindo a msma imagem

segue o codigo java que trata isso:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{

    response.setContentType("image/jpeg");
    ServletOutputStream sos = response.getOutputStream();

    byte[] bitFoto = null;

    try{
        FotoDao dao = new FotoDao();
        HttpSession session = request.getSession(true);

        List<Long> IDS = (List) session.getAttribute("IDS");

        for(Long id: IDS){

            Foto foto = dao.procuraFoto(id);
            bitFoto = foto.getFoto();
            sos.write(bitFoto);
            

        }

        sos.flush();
        sos.close();

        /*sos.write(bitFoto);

        sos.flush();*/


    }catch(Exception ex){
         ex.printStackTrace();
    }

}

e agora, segue o jsp que solicita…

Listar Fotos <% List fotoList = (List) request.getAttribute("FotoList"); List IDS = new ArrayList(); for (Iterator i = fotoList.iterator(); i.hasNext();) { Foto f = (Foto) i.next(); Long id = f.getId(); IDS.add(id); session.setAttribute("IDS", IDS); %> <% } // end For %>
Nome da Foto Foto
<%=f.getNome()%>

Voltar

alguem sabe me dizer pq isto ocorre?

abs, Rodrigo Pereira

Boa noite!

Ótimo tópico este, no entanto estou com o mesmo problema do [quote]RodPereira[/quote], minha tabela lista sempre a primeira imagem.