JSP não carrega outputstream gerado por JFreeChart

13 respostas
W

Boa Tarde tenho um jsp que via ajax chama um servlet passando parâmetro da seguinte forma

<%@ page contentType="text/html; charset=ISO-8859-1" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<div id="container-content">

<div id="menu-jsp">

<script type="text/javascript" src="js/jquery-1.7.1.js" ></script>
<script type="text/javascript" src="js/jquery.maskedinput-1.1.4.pack.js"/></script>

<script type="text/javascript">
function getquerystring() {
    var form     = document.forms['f1'];
    //gather form data into Javascript variables
    var word1 = form.Item.value;
    var word2 = form.Subitem.value;
    var word3 = form.De.value;
    var word4 = form.Ate.value;

    //form data is converted into a post string, the values would be used to create a dynamic chart
    qstr = 'item=' + escape(word1) + '&subitem='+ escape(word2)+'&de=' + escape(word3)+'&ate=' + escape(word4);
    var res='<img src="RelChartSatisfacao?'+qstr+'" />';//IMG tag is constructed here
    //set the DIV to the img tag 
    document.getElementById("divGraficos").innerHTML =res; 
}
</script>


<form>
Item:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
	<select name="item" id="item">
		<option value=""> Selecione um Item </option>
		<c:forEach var="frase" items="${frases}">
			<option value="${frase.id}">${frase.frase}</option>
		</c:forEach>
	</select>
	<br><br>

Subitem:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
	<select name="subitem" id="subitem"></select>
	<br><br>

Período de:&nbsp;
<input type="text" size="8" name="de" id="de" class="mesano"/>
&nbsp;Até&nbsp;
<input type="text" size="8" name="ate" id="ate" class="mesano"/>
	<br><br>

<a href="#" onclick="getquerystring()" class="gera">
		<img style="border: none;" alt="Gera Gráfico" src="img/btn_graf1.jpg" name="arrow">
</a>
<div id="divGraficos"></div>
</form>

a variável var res=’ do meu javascript se encarrega de chamar o servlet passando os dados inseridos pelo usuário.
O servlte trata os dados da seguinte forma com JFreeChart

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String frase = request.getParameter("item");
		String subFrase = request.getParameter("subitem");
		String de = request.getParameter("de");
		String ate = request.getParameter("ate");

		OutputStream out = response.getOutputStream();
			Connection connection = ConnectionFactoryHomolog.getConnection();
			JDBCCategoryDataset ds = new JDBCCategoryDataset(connection);
			try {
				ds.executeQuery("select r.nivelsatisfacao as satisfacao, count(1) as contador from relacionamento.satisfacao s join relacionamento.resposta r on s.id = r.satisfacao_id " +
				        "join relacionamento.subpergunta sub on sub.id = r.subpergunta_id join relacionamento.pergunta p on p.id = sub.pergunta_id " +
				        "where p.id = "+frase +" and sub.id = "+subFrase +" and to_char(s.data,'MM/yyyy') between '"+de+"' and '"+ate+"' " +
				        "group by r.nivelsatisfacao order by 1,2");

				JFreeChart chart = ChartFactory.createBarChart3D("Distribuição de Satisfação", "Satisfacao", "Quantidade", ds, PlotOrientation.VERTICAL, true, true, false);// create your chart
				response.setContentType("image/jpg"); /* Set the HTTP Response Type */
		        ChartUtilities.writeChartAsJPEG(out, chart, 640, 480);/* Write the data to the output stream */
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				out.close();
			}
	}

porque não visualizo a imagem na div que meu javascript manda ?

no internet explorer nao aparece nada, já no firefox aparecem vários caracteres estranhos do tipo:
����JFIF��Ca a a ��C aa ����"��a ���}!1AQaa"q2���#B��R��$3br� %&’()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz���������������������������������������������������������������������������a ���aw!1AQaaq"2�B���� #3R�br� $4�%�

o que estou fazendo de errado ?
Obrigado

p.s.: debugando consigo ver os dados inseridos chegando normalmente no servlet e também o resultado da query retorna perfeitamente

13 Respostas

E

O Firefox lhe deu uma pista importante - você viu os 4 caracteres “JFIF” que apareceram na saída? Isso indica que você está tentando mandar um arquivo JPEG dentro da própria página HTML - obviamente isso não pode ser feito dessa maneira, já que uma página HTML tem de referenciar um arquivo de imagem usando uma tag IMG em um arquivo separado.

Normalmente você usa uma taglib como a CeWolf. Isso consegue resolver esse problema de referenciar uma imagem em um arquivo separado, já que a taglib toma conta desse detalhe trágico.

W

comecei tentando usar cewolf, mas desisti, já que quando chamo meu objeto pela tag, ele lê novamente o dataset e assim roda a query novamente só que dessa vez com os dados dinâmicos nulos, já que ele não chama o servlet, onde tenho meu request pegando os dados passados pela tela, por isso fiquei 3 dias insistindo no cewolf e hoje desisti dele.
alguma ajuda para fazer isso sem cewolf

bjuncklaus

wjava:
comecei tentando usar cewolf, mas desisti, já que quando chamo meu objeto pela tag, ele lê novamente o dataset e assim roda a query novamente só que dessa vez com os dados dinâmicos nulos, já que ele não chama o servlet, onde tenho meu request pegando os dados passados pela tela, por isso fiquei 3 dias insistindo no cewolf e hoje desisti dele.
alguma ajuda para fazer isso sem cewolf

Opa, aqui eu faço tudo em uma classe auxiliar que é chamada pelo meu BackingBean. Essa classe gera uma imagem e salva como string, onde no meu xhtml eu utilizo a tag s:graphicImage (utlizo seam e jsf). Não sei como faria isso em jsp, mas vou dar uma olhada. :slight_smile:

W

bjuncklaus:
wjava:
comecei tentando usar cewolf, mas desisti, já que quando chamo meu objeto pela tag, ele lê novamente o dataset e assim roda a query novamente só que dessa vez com os dados dinâmicos nulos, já que ele não chama o servlet, onde tenho meu request pegando os dados passados pela tela, por isso fiquei 3 dias insistindo no cewolf e hoje desisti dele.
alguma ajuda para fazer isso sem cewolf

Opa, aqui eu faço tudo em uma classe auxiliar que é chamada pelo meu BackingBean. Essa classe gera uma imagem e salva como string, onde no meu xhtml eu utilizo a tag s:graphicImage (utlizo seam e jsf). Não sei como faria isso em jsp, mas vou dar uma olhada. :slight_smile:

obrigado por responder bjuncklaus,
aqui uso apenas servlet e jsp

obrigado

drsmachado

Se o problema todo é este, salve a imagem em um arquivo temporário. Após o uso da mesma, delete-o.

E

eu faço assim, não precisa de cwolf

public String gerarGrafico(ChartFormulario form,HttpServletRequest request, HttpServletResponse response) {
		try {
			response.setContentType("image/png");

			OutputStream outputStream = response.getOutputStream();

			JFreeChart chart = getChart();
			int width = 400;
			int height = 300;
			ChartUtilities.writeChartAsPNG(outputStream, chart, width, height);
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
public JFreeChart getChart() {
		DefaultPieDataset dataset = new DefaultPieDataset();
		dataset.setValue("Ford", 23.3);
		dataset.setValue("Chevy", 32.4);
		dataset.setValue("Yugo", 44.2);

		boolean legend = true;
		boolean tooltips = true;
		boolean urls = false;

		JFreeChart chart = ChartFactory.createPieChart("Cars", dataset, legend, tooltips, urls);

		chart.setBorderPaint(Color.GREEN);
		chart.setBorderStroke(new BasicStroke(5.0f));
		chart.setBorderVisible(true);

		return chart;
	}

e na jsp

<IMG SRC="ChartPage?acao=gerarGrafico" BORDER="0" >
bjuncklaus
eduJava:
eu faço assim, não precisa de cwolf
public String gerarGrafico(ChartFormulario form,HttpServletRequest request, HttpServletResponse response) {
		try {
			response.setContentType("image/png");

			OutputStream outputStream = response.getOutputStream();

			JFreeChart chart = getChart();
			int width = 400;
			int height = 300;
			ChartUtilities.writeChartAsPNG(outputStream, chart, width, height);
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
public JFreeChart getChart() {
		DefaultPieDataset dataset = new DefaultPieDataset();
		dataset.setValue("Ford", 23.3);
		dataset.setValue("Chevy", 32.4);
		dataset.setValue("Yugo", 44.2);

		boolean legend = true;
		boolean tooltips = true;
		boolean urls = false;

		JFreeChart chart = ChartFactory.createPieChart("Cars", dataset, legend, tooltips, urls);

		chart.setBorderPaint(Color.GREEN);
		chart.setBorderStroke(new BasicStroke(5.0f));
		chart.setBorderVisible(true);

		return chart;
	}

e na jsp

<IMG SRC="ChartPage?acao=gerarGrafico" BORDER="0" >

Isso, é bem parecido com o que eu faço, só muda o html. No meu caso eu utilizo uma tag do seam. Acho que isso resolve wjava.

W

bjuncklaus

criei exatamente o seu exemplo no meu código, mas meu problema é o atributo src da tag img ter que iniciar um servlet, pois preciso passar dados para a string que vai rodar o sql no banco e desses dados do banco popular o dataset.

tenho o seguinte javascript para tentar fazer isso:

$(document).ready(function() {
	$("a").click(function() {
		alert($("#item").val() + " - " + $("#subitem").val() + " - " + $("#de").val() + " - "+ $("#ate").val());
		$.post("/Portal/RelChartSatisfacao", {
			'sql' : "select r.nivelsatisfacao as satisfacao, count(1) as contador from relacionamento.satisfacao s join relacionamento.resposta r on s.id = r.satisfacao_id join relacionamento.subpergunta sub on sub.id = r.subpergunta_id join relacionamento.pergunta p on p.id = sub.pergunta_id where p.id = "+$("#item").val()+" and sub.id = "+$("#subitem").val()+" and to_char(s.data,'MM/yyyy') between '"+$("#de").val()+"' and '"+$("#de").val()+"' group by r.nivelsatisfacao order by 1,2"
		},
		function (data) {
			$("#divGraficos").html(data);
		},
		"html"); 
     });
});
<div id="divGraficos"></div>

Entro direitinho no servlet e recebo os dados por request.
Mas na tela, onde deveria aparecer o gráfico, aparece apenas �PNG (mudei o método para gerar .png, mas não adiantou)

W

wjava:
bjuncklaus

criei exatamente o seu exemplo no meu código, mas meu problema é o atributo src da tag img ter que iniciar um servlet, pois preciso passar dados para a string que vai rodar o sql no banco e desses dados do banco popular o dataset.

tenho o seguinte javascript para tentar fazer isso:

$(document).ready(function() {
	$("a").click(function() {
		alert($("#item").val() + " - " + $("#subitem").val() + " - " + $("#de").val() + " - "+ $("#ate").val());
		$.post("/Portal/RelChartSatisfacao", {
			'sql' : "select as colunas que eu quero from tabelas where aid = "+$("#item").val()+" and bid = "+$("#subitem").val()+" and to_char(s.data,'MM/yyyy') between '"+$("#de").val()+"' and '"+$("#de").val()+"'
		},
		function (data) {
			$("#divGraficos").html(data);
		},
		"html"); 
     });
});
<div id="divGraficos"></div>

Entro direitinho no servlet e recebo os dados por request.
Mas na tela, onde deveria aparecer o gráfico, aparece apenas �PNG (mudei o método para gerar .png, mas não adiantou)

Alguém sabe como faço pra meu javascript gerar o dado na tag img ao invés de jogar direto no html ?

function (data) {
			$("#divGraficos").html(data);
		},
		"html");

no código acima, um modo de mandar como imagem, mas dentro da tag img ?

E

http://api.jquery.com/attr/

$("img").attr({ src: "/images/hat.gif", title: "jQuery", alt: "jQuery Logo" });

E

mais não funciona assim
quando vc tem uma imagem e vc altera o src, ele automaticamente ja pega esse src e faz uma chamada e tenta pegar o retorno que no caso é um png.
entao ali vc não precisa fazer um post nem nada, coloque somente o caminho do metodo com os parametros no src que ele vai funcionar
falow

W

tinham dois problemas, primeiro colocar minha div depois do form e segundo criar um javascript direito dessa forma:

function getquerystring() {
    var sql = "select colunas from tabelas where aid = "+$("#item").val()+" and bid = "+$("#subitem").val()+" and to_char(s.data,'MM/yyyy') between '"+$("#de").val()+"' and '"+$("#de").val()+"';
    var res='<img src="/Portal/RelChartSatisfacao?query='+sql+'" />';
    document.getElementById("divGraficos").innerHTML =res; 
}

e meu botão simplesmente chama esse javascript

<a href="#" onclick="getquerystring()" style="border: none;">
		<img style="border: none;" alt="Gera Gráfico" src="img/btn_graf1.jpg" name="arrow">
</a>
E

isso aew
uma dica

coloque nos seus parametros do seu form serializado e faça o sql no servidor

falow bicho

Criado 30 de julho de 2012
Ultima resposta 31 de jul. de 2012
Respostas 13
Participantes 5