Gerando PDF + Perdendo session

Fala pessoal, blz?

Estou gerando PDF desta URL:

Acesso pelo browser e ele me gera o HTML perfeito. Agora, para baixar o PDF disto, acesso outra URL:

Onde tenho esse código no PdfController:

public void job(Long projetoId)
	{
		Html2Pdf html2pdf = new Html2Pdf();
		try
		{
			response.setContentType("application/pdf");
			URL url = new URL("http://localhost:8080/Sigo/pdf/gerar/job?projetoId=" + Long.toString(projetoId));
			URLConnection urlConn = url.openConnection();
			InputStream is = urlConn.getInputStream();
			OutputStream out = response.getOutputStream();
			
			html2pdf.convert(is, out);
			out.close();
		} catch (MalformedURLException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		} catch (DocumentException e)
		{
			e.printStackTrace();
		}
	}

O problema é: estou com lazy no hibernate, então, quando acesso pelo browser (primeira URL), o HTML é gerado perfeitamente. Ao acessar o controller que irá gerar o PDF, acesso a URL pela classe URL do Java, para poder utilizar os streams de in/out e gerar o PDF. Dessa forma, não tenho sessão inicializada acessando por new URL(), então o PDF não é gerado corretamente.

Como posso solucionar isso?

Estou usando VRaptor + Hibernate + Velocity + iText + Flying Saucer + jTidy

abs!

Galera, ninguém tem nenhuma sugestão? Como poderia resolver isso? Essa forma que estou fazendo é a melhor para gerar PDFs?

abs.

O problema nesse seu caso que você não acessa por um browser, e sim pelo Java, já que você usa um URL.getInputStream(). Assim mesmo que esse método seja acessado via browser, internamente o acesso é feito pelo Java em outra http-session.

Minha sugestão é que você repense a forma de fazer esse relatório. O melhor é fazer o acesso direto ao invés dessa loucura de abrir um stream. Caso contrário não há nada o que fazer.

Eu pesquisei aqui mesmo no fórum as formas de gerar um PDF de uma URL e cheguei nesta solução.
Qual outra forma seria? Já tenho a URL e os HTMLs perfeitos para serem transformados em PDF, estou esbarrando nesse problema mesmo de ser outra session.

Pelo que entendi você tem no endereço http://localhost:8080/Sigo/pdf/gerar/job?projetoId=xxx uma página normal, com saída em HTML, correto? Então você usa um método que converte esse HTML em PDF, por isso você acaba fazendo esse acesso via Java.

Porque então ao invés de fazer um HTML ser transformado em PDF você não gera a página direto em PDF? Se você usar um ireport ou itext eles já geram o PDF, sem precisar fazer transformações assim.

Desculpe não saber mais como te ajudar, pois não sei bem qual o contexto disso tudo. Mas creio que a solução seja essa, criar uma página que gere o PDF direto ao invés de converter o HTML para PDF.

É exatamente isso q vc disse!

Mas, se eu for gerar automaticamente o PDF sem passar por essa URL do HTML, como vou “layoutar” minha página? Pois a página está estruturada já com o CSS certinho.

Você manda o layout completo de um site para um PDF? Meu deus, imagino o tonner que gasta para impressão.

Não sei bem o objetivo disso, mas se você realmente precisa não há como fazer sem fazer tudo de novo usando as ferramentas de gerar PDF.

hahahaha, sim, realmente gastaria muito tonner! Mas esse HTML que transformo para PDF contém apenas a tela para impressao mesmo 8)

Bom, to vendo que vou ter que refazer essa parte mesmo…

Estou usando o iText para gerar esse meu PDF atual. Segue o código da classe Html2Pdf:

public void convert(InputStream input, OutputStream out) throws DocumentException
{
    	Tidy tidy = new Tidy();        	
    	Document doc = tidy.parseDOM(input, null);
        ITextRenderer renderer = new ITextRenderer();
        renderer.setDocument(doc, null);
        renderer.layout();
        renderer.createPDF(out);
}	

O jTidy está interpretando pra mim o InputStream, que no caso é minha página HTML (método parseDOM).
Após isso, o iText gera o PDF pra mim no response.getOutputStream(), já aparecendo na tela do usuário o PDF.

Pode me dar os passos para iniciar essa mudança? Como aplicar o layout(css) já pronto?

abs e obrigado

Voce foi até na china pra chegar na casa do vizinho. Não sei o seu grau de investigação mas o que todos usam é a dupla Jasper+iReport pra gerar relatorios e formularios em qualquer tipo de saida(PDF, XLS, CVS, etc) o Jasper é o framework de geração que usa um arquivo XML com o formato do que vc quer e o iReport é a ferramenta grafica no estilo do CrystalReport aonde vc desenha e ele gera esse arquivo XML(na verdade ele tem a terminção como JRXML)

Vendramini87, meu conhecimento acaba por aqui, pois não sei mexer nesses geradores de PDF.

Creio que o ideal é vocẽ abrir um tópico no subfórum “Ferramentas, Frameworks e Utilitários” para sanar melhor as dúvidas sobre itex, ireport e afins.

Passei por esse problema mais estava utilizando JSF, eu resolvi passando o id da sessão do JSF na URL que será executada pelo java, por exemplo essa URL que você usou : URL url = new URL(“http://localhost:8080/Sigo/pdf/gerar/job?projetoId=” + Long.toString(projetoId));
Passando o ID da sessão do jfs, então ficaria assim :

HttpSession session = (HttpSession) externalContext.getSession(true);
URL url = new URL("http://localhost:8080/Sigo/pdf/gerar/job?projetoId=" + Long.toString(projetoId)) + ";jsessionid=" + session.getId();

Assim você consegue capturar os objetos da sessão no seu arquivo que será gerado o pdf, agora se não tiver usando o JSF e sim outro framework, da uma olhada no ID sessão que ele gera, e tente passar na URL.