Como faço para exibir um BufferedImage numa pagina jsp?

34 respostas
felbicmel

E ae pessoal tudo bem???

Gostaria de saber se alguem poderia me ajudar em como fazer para mostrar um BufferedImage na minha pagina JSP.
Tenho uma classe me Java que cria essa imagem e me retornava como parametro o caminho de onde eu salvava essa imagem, porem quando rodo minha aplicação via browser a imagem nao carrega pois o Tomcat nao tem acesso as pastas onde eu crio essa imagem, então ao invés de gravar essa imagem eu gostaria de passá-la direto para a JSP.

Espero que alguem possa me ajudar

Vlw

34 Respostas

Lucas_Cavalcanti

você pode criar uma Servlet/Action/Logica que retorna essa BufferedImage como InputStream (que escreva o input stream dela no response)…

daí vc coloca no html o caminho pra essa Servlet/Action/Logica

tem frameworks que tornam isso mais fácil, como por exemplo o VRaptor:
http://vraptor.caelum.com.br/

felbicmel

Lucas acho que entendi o que você disse…

Sou novo em Java e não tenho muita facilidade ainda com essa linguagem…

Será que não teria um exemplo, mesmo que simples, para eu entender melhor isso??!?!

Obrigado pela dica já

Lucas_Cavalcanti

pra continuar com a sua solução de criar a imagem numa pasta específica, que talvez seja mais simples, vc pode fazer o seguinte:

String caminhoPasta = servletContext.getRealPath("/algumaPasta"); // uma pasta dentro da sua aplicação
File pasta = new File(caminhoPasta);
pasta.mkdir(); //se a pasta não existir, cria

aí é só salvar a imagem dentro dessa pasta (com esse File) e pra acessar no jsp, basta colocar o caminho a partir desse /algumaPasta:

<img src="<c:url value="/algumaPasta/nomeDaImagem.png"/>" alt="Descricao" />

pra conseguir o servletContext depende do que vc tah usando para fazer sua aplicação… o que é?

felbicmel

E ae Lucas,

Então estou usando o Eclipse e o TomCat.
Isso de criar uma pasta e salvar a imagem nela eu estava fazendo, ai quando eu rodo minha aplicação pelo Eclipse funciona normalmente, porém quando eu rodo minha aplicação só pelo TomCat, subindo o meu arquivo .WAR no meu localhost porta 8080, a imagem não aparece.

Por isso que queria saber de alguma maneira de mostrar direto a imagem na minha página sem precisar salvar essa imagem, uma vez que o Tomcat não enxerga as minhas pastas locais.

Espero que possa me ajudar com isso.

Vlw pelas dicas até agora

Lucas_Cavalcanti

bom, se vc configurar o tomcat pra extrair o war, talvez funcione criar as pastas…

mas enfim, a pergunta q eu fiz era sobre quais frameworks vc tah usando, ou se não tá usando nenhum… é Servlet ou é JSF?

felbicmel

Ah ta entendi…

Eu disse que sou novo nisso… entao estou usando Servlets mesmo…

Espero que possa me ajudar… to ficando louco com isso já…

Lucas_Cavalcanti

evite usar servlets direto, use algum framework, como o VRaptor:

http://vraptor.caelum.com.br/documentacao
http://www.caelum.com.br/curso/fj-28-vraptor-hibernate-ajax/

no VRaptor, fazer isso é algo parecido com:

@Resource
public class ImagensController {
     
     public InputStream imagem(String nome) {
         BufferedImage image = // lógica de carregar a imagem
         return ImageIO.createImageInputStream(image);
     }
}
felbicmel

E ae cara fmz???

Entao eu tenho q usar o Servlet assim pois eh um trabalho para a facul…

Tentei fazer o que voce mostrou abaixo usando o ImageIO.createImageInputStream, mas quando uso ele o que me retorna eh o valor NULL

Sabe o por que???

Dentro do ImageIO.createImageInputStream eu passei minha imagem do tipo BufferedImage

Fico noa guardo…

Vlw

Lucas_Cavalcanti

o seu BufferedImage tem uma imagem de verdade dentro?

felbicmel

tem sim… eu usava ele para gravar essa imagem na minha maquina e depois puxar de lá… mas como eu disse… quando rodo direto pelo TomCat ele nao consegue achar essa imagem gravada na minha maquina por nao enxergar as pastas da minha maquina… por isso que eu achei estranho estar vindo NULL

Lucas_Cavalcanti

ele vai enchergar as pastas da sua máquina desde que vc coloque o caminho absoluto delas…

mas se vc vai usar alguma imagem, ela deveria estar dentro da sua aplicação mesmo… dentro da pasta WebContent, por exemplo

felbicmel

então cara só que o meu problema é que eu não tenho essa imagem gravada nas minhas pastas.

o que eu estava fazendo era gerando essa imagem em uma classe e depois gravava essa imagem, ai na minha pagina JSP eu indicava o caminho e a psgina JSP conseguia puxar essa imagem, porem isso só no Eclipse, quando eu rodo direto pelo TomCat nao aparece a imagem.

Então a minha outra possibilidade seria gravar essa imagem em algum lugar em que o TomCat conseguisse acesso, você comentou de passar o caminho absoluto.

Como faço para pegar essa caminho absoluto??!?!

Vlw

felbicmel

então cara só que o meu problema é que eu não tenho essa imagem gravada nas minhas pastas.

o que eu estava fazendo era gerando essa imagem em uma classe e depois gravava essa imagem, ai na minha pagina JSP eu indicava o caminho e a psgina JSP conseguia puxar essa imagem, porem isso só no Eclipse, quando eu rodo direto pelo TomCat nao aparece a imagem.

Então a minha outra possibilidade seria gravar essa imagem em algum lugar em que o TomCat conseguisse acesso, você comentou de passar o caminho absoluto.

Como faço para pegar essa caminho absoluto??!?!

Vlw

Lucas_Cavalcanti

como vc tah gerando a imagem?

felbicmel

Então,

Eu estou usando o JFreeChart para a criação de um gráfico, então eu passo as informações para gerar as o meu grafico e dou um createBufferedImage.

Eu sei que vem algum resultado disso, pois como comentei antes eu estava gravando essa imagem na minha maquina e gravava normalmente.

Lucas_Cavalcanti

faz o seguinte, na sua aplicação dentro do tomcat:

BufferedImage image = chart.createBufferedImage(...);
File teste = new File("C:\teste"); // ou similar se vc usa linux
teste.mkdir();
//salve a imagem na pasta teste

abra a pasta C:\teste e veja se a imagem está lá…

se sim, troque a lógica de salvar num arquivo pra lógica de criar um InputStream e veja se tb funciona

felbicmel

Acabei de fazer o teste…

para criar minha imagem estou fazendo

ImageIO.write(obj.ImagemGrafico(), “jpg”, file)

onde esse obj.ImagemGrafico() retorna um BufferedImage e o file é a pasta que eu criei… isso funciona normalmente

agora quando uso

ImageInputStream iis = ImageIO.createImageInputStream(obj.ImagemGrafico());

a variavel iss fica com o valor NULL

eu deixei as duas logicas juntas para ver se realmente estava criando o arquivo e realmente está… só nao criar o ImageInputStream

Lucas_Cavalcanti

se vc quer só escrever na response é só fazer isso:

ImageIO.write(obj.ImagemGrafico(), "jpg", response.getOutputStream());
felbicmel

E ae kra fmz?

bom é quase isso que eu quero… deu certo agora… quando eu executo ele mostra um “pagina” somente com a minha imagem…

o que preciso agora é colocar essa imagem dentro da minha pagina…

eu estava fazendo assim…

<img src="<%= request.getSession().getAttribute(“grafico”) %>" />

espero que possa me ajudar… vlw mais uma vez

Lucas_Cavalcanti

aí que tá, vc tem que fazer essa Servlet que só mostra a imagem, e colocar na sua página:

<img src="/url/da/servlet" />

entendeu?

não tem como fazer de outro jeito (até dá pra serializar a imagem no html, mas é meio estranho)

felbicmel

eu entendi a idéia, mas nao entendi como fazer… vou postar o que tenho para ver se consegue me dar essa ultima forcinha…

Tenho um Servlet chamada ctrGrafico que possui o seguinte trecho:

Grafico obj = new Grafico(lstParam);
			if (obj.GeraGrafico()) {
				req.getSession().setAttribute("grafico", ImageIO.write(obj.ImagemGrafico(), "jpg", resp.getOutputStream()));
				req.getRequestDispatcher("/respGrafico.jsp").forward(req, resp);
			}

e minha paginha de retorno respGrafico.jsp está com a seguinte linha…

<td>
              <img src="<%= request.getSession().getAttribute("grafico") %>" />
	        </td>

Eu entendi que preciso chamar outra Servlet, já que essa nova Servlet só me retornaria a imagem que quero, porém nao entendi como que eu mostraria esse retorno na pagina ou na outra servlet, uma vez que as informações que eu tenho que passar para a nova Servlet que estão na Servlet ctrGrafico.

Espero que possa me ajudar…

Lucas_Cavalcanti

não faça a lógica de gerar o gráfico na servlet que redireciona pro jsp, faça na servlet que só gera a imagem

como vc recebe os parâmetros pra gerar o grafico?

suponha que sejam os parametros a, b e c, daí vc vai colocar na sua jsp:

<img src="/url/da/servlet?a=${param.a}&b=${param.b}&c=${param.c}"/>

assim vc consegue pegar os parametros na servlet de imagem, gerar o gráfico e exibir…

felbicmel

o que acontece é o seguinte, tenho uma pagina JSP onde o usuario escolhe o tipo do grafico que ele quer, com essa informação eu vou no Banco de Dados e faço um select para trazer as informações que preciso para montar o grafico…

Se houverem informações eu monto o grafico caso contrario eu mando para uma outra pagina informando que nao foi possivel gerar o grafico…

segue esse trecho:

List<String> lstParam = new ArrayList<String>();
lstParam.add(req.getParameter("tipRelat"));
lstParam.add(req.getParameter("codLoja"));
lstParam.add(req.getParameter("periodo"));
lstParam.add(req.getParameter("dataIni"));
lstParam.add(req.getParameter("dataFim"));

Grafico obj = new Grafico(lstParam);
if (obj.GeraGrafico()) {
	req.getSession().setAttribute("grafico", ImageIO.write(obj.ImagemGrafico(), "jpg", response.getOutputStream()));
	req.getRequestDispatcher("/respGrafico.jsp").forward(req, resp);
}
else {
	req.getSession().setAttribute("erro", "Não há dados para geração desse relatório");
	req.getRequestDispatcher("/respRelatorio.jsp").forward(req, resp);
}

Ai dentro da minha pagina respGrafico.jsp que a tag chamava o atributo grafico.
Como eu já tenho as informações para a geração do grafico, como que eu passaria essas informações para a nova Servlet e como ficaria a estrutura dessa Servlet??!?

Lucas_Cavalcanti

vc pode fazer nesse servlet:

if (obj.GeraGrafico()) {  
    req.getSession().setAttribute("grafico", obj.ImagemGrafico());
 ....

e na servlet que mostra a imagem:

BufferedImage image = (BufferedImage) req.getSession().getAttribute("grafico");

ImageIO.write(image, "jpg", response.getOutputStream()));

daí vc não precisa ficar repassando os parâmetros…

felbicmel

Entendi, só uma coisa… como faço a chamada entao!!!

o nome da minha package é TCC.ctrl e eu coloquei da seguinte forma e nao me retornou nada

<img src="/TCC/ctrl/GeraGrafico" />
Lucas_Cavalcanti

não é pelo pacote…

é pelo mapping que vc colocou no web.xml…

felbicmel

Meu XML tem as seguintes linhas

<servlet>
		<description>
		</description>
		<display-name>
		GeraGrafico</display-name>
		<servlet-name>GeraGrafico</servlet-name>
		<servlet-class>
		TCC.ctrl.GeraGrafico</servlet-class>
	</servlet>
 	<servlet-mapping>
 		<servlet-name>GeraGrafico</servlet-name>
 		<url-pattern>/GeraGrafico</url-pattern>
 	</servlet-mapping>

como ficaria entao a chamada na tag IMG???

<img src="/GeraGrafico" />

porque se for isso, nao deu certo nao…

Lucas_Cavalcanti
<img src="/<nome do contexto>/GeraGrafico" />

é o certo

felbicmel

o que é esse nome do contexto???

to perdidão nessa parte…

vlw

felbicmel

se o nome do contexto for o nome do meu projeto, o nome que fica no browser… ele é prjGAD

no browser fica assim…

http://localhost:8080/prjGAD/index.jsp

coloquei isso na tag IMG e tb nao deu certo

<img src="/prjGAD/GeraGrafico" />
Lucas_Cavalcanti

posta aqui por favor os servlets que vc tah usando pra gerar esse gráfico, os mappings e o jsp…

pode remover as partes irrelevantes pra esse problema

felbicmel
servlet que é chamado da minha pagina JSP
package TCC.ctrl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import TCC.modelo.Grafico;

public class ctrGrafico extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ctrGrafico() {
        super();
    }

	protected void doGet(HttpServletRequest req, 
			 			 HttpServletResponse resp) throws ServletException, IOException {
		Executa(req,resp);
	}
	
	protected void doPost(HttpServletRequest req, 
				  		  HttpServletResponse resp) throws ServletException, IOException {
		Executa(req,resp);
	}
	
	private void Executa(HttpServletRequest req, 
						 HttpServletResponse resp) throws ServletException, IOException {
		
		if (req.getParameter("opcao").equals("geraGrafico")) {

			List<String> lstParam = new ArrayList<String>();
			lstParam.add(req.getParameter("tipRelat"));
			lstParam.add(req.getParameter("codLoja"));
			lstParam.add(req.getParameter("periodo"));
			lstParam.add(req.getParameter("dataIni"));
			lstParam.add(req.getParameter("dataFim"));

			Grafico obj = new Grafico(lstParam);
			if (obj.GeraGrafico()) {
				req.getSession().setAttribute("grafico", obj.ImagemGrafico());
				req.getRequestDispatcher("/respGrafico.jsp").forward(req, resp);
			}
			else {
				req.getSession().setAttribute("erro", "Não há dados para geração desse relatório");
				req.getRequestDispatcher("/respRelatorio.jsp").forward(req, resp);
			}
		}
		else {
			req.getSession().setAttribute("erro", "Erro inesperado");
			req.getRequestDispatcher("/relatorio.jsp").forward(req, resp);
		}
	}
}
classe que gera o grafico
public boolean GeraGrafico() {
		GraficoDAO obj = new GraficoDAO(_tipRelat, _param);
		
		if (obj.GeraGrafico()) {
			_titGrafico = obj.TituloGrafico();
			_titEixoX = obj.TituloEixoX(); 
			_titEixoY = obj.TituloEixoY();
			_lstConteudo = obj.ListaConteudo();
			_nomGraf = obj.NomeGrafico();
			
			try {
				_imagem = Geral.GeraGrafico(_titGrafico, _titEixoX, 
						  					_titEixoY, _lstConteudo,
						  					ModeloGrafico.BARRA_VERTICAL_3D);
				return true;
			} catch (Exception ex) {
	            ex.printStackTrace();
	        }
		}
		return false;
	}
classe chamada para gerar o grafico
public static BufferedImage GeraGrafico(String pTitGrafico, 
    										String pTitEixoX,
    										String pTitEixoY, 
    										List<GraficoItemTO> pLstValores,
    										ModeloGrafico pModeloGraf) throws Exception {
    	try {
    		int numLojas = pLstValores.size();
            DefaultCategoryDataset ds = new DefaultCategoryDataset();
            for (int ind = 0; ind < pLstValores.size(); ind ++) {
            	ds.addValue(pLstValores.get(ind).Valor1(),
	            			pLstValores.get(ind).Valor2(),
	            			pLstValores.get(ind).Valor3());
            }
            JFreeChart chart;
            if (pModeloGraf == ModeloGrafico.BARRA_HORIZONTAL)
            	chart = ChartFactory.createBarChart(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
            										PlotOrientation.HORIZONTAL, true, false, false);
            else if (pModeloGraf == ModeloGrafico.BARRA_HORIZONTAL_3D)
            	chart = ChartFactory.createBarChart3D(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
						  							  PlotOrientation.HORIZONTAL, true, false, false);
            else if (pModeloGraf == ModeloGrafico.BARRA_VERTICAL)
            	chart = ChartFactory.createBarChart(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
													PlotOrientation.VERTICAL, true, false, false);
			else if (pModeloGraf == ModeloGrafico.BARRA_VERTICAL_3D)
				chart = ChartFactory.createBarChart3D(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
										  			  PlotOrientation.VERTICAL, true, false, false);
			else if (pModeloGraf == ModeloGrafico.LINHA_HORIZONTAL)
            	chart = ChartFactory.createLineChart(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
													 PlotOrientation.HORIZONTAL, true, false, false);
			else if (pModeloGraf == ModeloGrafico.LINHA_HORIZONTAL_3D)
				chart = ChartFactory.createLineChart3D(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
										  		   	   PlotOrientation.HORIZONTAL, true, false, false);
			else if (pModeloGraf == ModeloGrafico.LINHA_VERTICAL)
				chart = ChartFactory.createLineChart(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
													 PlotOrientation.VERTICAL, true, false, false);
			else if (pModeloGraf == ModeloGrafico.LINHA_VERTICAL_3D)
				chart = ChartFactory.createLineChart3D(pTitGrafico, pTitEixoX, pTitEixoY, ds, 
						  			  				   PlotOrientation.VERTICAL, true, false, false);
            else
            	return null;
            chart.setBorderVisible(true);
            chart.setBorderPaint(Color.black);
            int tamFig = 100;
            if (numLojas > 1 && numLojas <= 10)
            	tamFig = numLojas * 60;
            else if (numLojas > 10)
            	tamFig = 600;
            return chart.createBufferedImage(tamFig, 300);

        } catch (Exception e) {
        	e.printStackTrace(); 
        }
        return null;
    }
pagina JSP de resposta
<html>
<head>
<title>SGAD - Software de Gerenciamento e Apoio a Decisão</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="./estilo.css" />
</head>
<body>
<div align="center">
<form name="form1" method="post" action="ctrRelatorio">
  <input type="hidden" id="opcao" name="opcao" value="geraGrafico"/>
  <!-- Tabela com 4 linhas e 2 colunas -->
  <table width="750" height="610" border="0" cellpadding="0" cellspacing="0">
    <!-- Linha onde fica a parte superior (logo) -->
    <tr>
	  <td height="130" colspan="2" class="imagemLogo">
	    <h1> SGAD - Software de Gerenciamento e Apoio a Decisão </h1>
	  </td>
    </tr>
	<!-- Linha que pode mostrar informacoes do usuario -->
	<tr height="20">
      <td width="750" class="corMenu" colspan="2">
        <p> Perfil do Usu&aacute;rio: 
	        <%=request.getSession().getAttribute("perfil") %> 
	        - Bem Vindo 
	        <%=request.getSession().getAttribute("nomUser") %> </p> 
	  </td>
    </tr>
    <tr height="450">
	<!-- Coluna que recebe uma tabela onde fica o menu lateral -->
      <td width="150" class="corMenu">
        <table height="100%" width="100%" border="0" cellpadding="0" cellspacing="0">
          <tr>
            <td class="corMenuLatTopo" height="30"> </td>
          </tr>
		  <tr>
            <td class="corMenuLat">
              <p style="margin-left: 5"> <a href="Principal?pag=Relatorio" class="menu"> Rel&aacute;torios </a> </p>
            </td> 
          </tr>
		  <tr>
            <td class="corMenuLat">
              <p style="margin-left: 5"> <a href="Principal?pag=Regras" class="menu"> Regras </a> </p> 
            </td>
          </tr>
		  <tr>
            <td class="itemSelecionado">
              <p style="margin-left: 5"> <a href="Principal?pag=Pesquisa" class="menu"> Busca e Pesquisa </a> </p> 
            </td>
          </tr>
		  <tr>
            <td class="corMenuLat">
              <p style="margin-left: 5"> <a href="Principal?pag=Logoff" class="menu"> Logoff </a> </p> 
            </td>
          </tr>
          <tr>
            <td width="100%" height="100%"> </td>
          </tr>
        </table>
      </td>
	  <!-- Coluna que recebe uma tabela onde fica o conteudo de cada pagina -->
	  <td width="600" align="right">
        <table height="100%" border="0" align="center" cellpadding="1" cellspacing="1">
          <tr> <td height="30"> </td> </tr>
          <tr>
            <td height="30" align="center">
              <h2> <%= request.getSession().getAttribute("descricao").toString()%> </h2>
            </td>
          </tr>
          <tr>
            <td>
              <img src="/prjGAD/GeraGrafico" />
	        </td>
	      </tr>
          <tr>
            <td height="100%" width="100%"> </td>
          </tr>
		</table>
      </td>
    </tr>
	<!-- Linha final -->
    <tr>
      <td colspan="2" width="750" height="10" class="corMenu">
      </td>
    </tr>
  </table>
</form>
</div>
</body>
</html>

e por fim a nova Servlet que eu criei

package TCC.ctrl;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GeraGrafico extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public GeraGrafico() {
        super();
    }
    
    protected void doGet(HttpServletRequest request, 
			  HttpServletResponse response) throws ServletException, IOException {
    	
    }

	protected void doPost(HttpServletRequest request, 
						  HttpServletResponse response) throws ServletException, IOException {
		BufferedImage image = (BufferedImage) request.getSession().getAttribute("grafico"); 
		ImageIO.write(image, "jpg", response.getOutputStream());
	}

}

Espero que ajude, existem alguns ENUM e classes auxiliares que uso... mas se colocar todas vai ficar enorme aqui

Lucas_Cavalcanti

o problema é que vc colocou o código do servlet GeraGrafico no doPost, e tah fazendo um Get…

de qqer forma, troque o:

protected void doGet(HttpServletRequest req, 
			 			 HttpServletResponse resp) throws ServletException, IOException {
		Executa(req,resp);
	}
	
	protected void doPost(HttpServletRequest req, 
				  		  HttpServletResponse resp) throws ServletException, IOException {
		Executa(req,resp);
	}
	
	private void Executa(HttpServletRequest req, 
						 HttpServletResponse resp) throws ServletException, IOException {

por:

protected void service(HttpServletRequest req, 
			 			 HttpServletResponse resp) throws ServletException, IOException {

ou seja, se vc não se importa se é get ou post, vc pode sobrescrever o service… só sobrescreva o doGet e doPost se vc for fazer coisas diferentes neles, ou se vc quer proibir um deles

felbicmel

vlw Lucas… é deu certinho agora… vlw mesmo… estava a semanas tentando resolver esse problema…

vlw mesmo

Criado 14 de agosto de 2010
Ultima resposta 19 de ago. de 2010
Respostas 34
Participantes 2