Recuperar Imagem campo BLOB e exibir numa JSP

15 respostas
J

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

15 Respostas

J

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">
J

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

J

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

J

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)
J

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.

R

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

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>
J

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>
J

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.

J

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.

J

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

R

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?

J

Amigo você já conseguiu resolver esse problema!

R

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

D

Boa noite!

Ótimo tópico este, no entanto estou com o mesmo problema do

RodPereira
, minha tabela lista sempre a primeira imagem.

Criado 21 de fevereiro de 2007
Ultima resposta 3 de dez. de 2013
Respostas 15
Participantes 6