Dúvida <h:command

Olá pessoal, estou trabalhando com JSF e preciso de um objeto HttpServletResponse para enviar um stream como resposta ao browser do cliente mas acontece o seguinte, quando clico no meu command button o método acessado por ele não consegue obter um HttpServletResponse de ExternalContext, ele obtem qualquer objeto, menos esse e também o ResponseStream. Alguem pode me dizer se isso é um comportamento normal da tag h:command? Alguem há passou por situação parecida?
Alguem sabe como posso devolver um stream ao browser de uma outra forma?

Olá,

Não há nenhum problema com o command. Utilizei-o da seguinte forma e funcionou para um relatório gerado com o jasper reports:

public FacesContext getFacesContext() {
    return FacesContext.getCurrentInstance();
}

public HttpServletResponse getResponse() {
    return (HttpServletResponse) getFacesContext().getExternalContext().getResponse();
}

public String gerarRelatorio() {
	GerarRelatorioEquipamentos rel = new GerarRelatorioEquipamentos( true );

	rel.setRedeId(ddlRede.getValue().toString());
	
	if (ddlLoja.getValue() != null) {
		rel.setLojaId(ddlLoja.getValue().toString());
	} else {
		rel.setLojaId(null);
	}

	rel.setInicioMes(Integer.parseInt(ddlDeMes.getValue().toString()));
	rel.setInicioAno(Integer.parseInt(ddlDeAno.getValue().toString()));
	rel.setFimMes(Integer.parseInt(ddlAteMes.getValue().toString()));
	rel.setFimAno(Integer.parseInt(ddlAteAno.getValue().toString()));
	
	if (rel.getInicioAno() * 100 + rel.getInicioMes() > rel.getFimAno() * 100 + rel.getFimMes()) {
		adicionarMensagemDeErro("O período 'De-Até' deve ser um período válido.");
		
		return null;
	}

	rel.setRede(recuperarTextoSelecionadoDoDropDown(ddlRede));

	if (rel.getLojaId() == null || "".equals(rel.getLojaId())) {
		rel.setLoja("Todas as lojas");
	} else {
		rel.setLoja(recuperarTextoSelecionadoDoDropDown(ddlLoja));
	}
	
	rel.executar();
	
	adicionarErros(rel.getInconsistencias());
	
	if (isValid()) {
		getResponse().setContentType("application/pdf");
		try {
			getResponse().setContentLength(rel.getRelatorio().length);
			getResponse().getOutputStream().write(rel.getRelatorio());
			getFacesContext().responseComplete();
		} catch (IOException e) {
			throw new ExFoster(e.getMessage(), e);
		}
	}
	
	return null;
}

Espero que esse código lhe ajude,

Abraços

Valeu pela dica, mas o problema é justamente este getResponse, eu acabei de implementar os seus métodos e o retorn do método getResponse foi null, já estou arrancando o que me resta de cabelos

valeu pela dica

Olá…

Talvez seja a implementação do jsf que você está utilizando. A que eu utilizei foi Myfaces…

Qual seria a que você está utilizando?

Como a suspeitar disso tb, nesse projeto estou fazendo uso do icefaces, para ter acesso a algumas funcionalidades do ajax sem ter q faze-las no braço é tanto que qnd eu uso o System.out. … sempre obtenho este tipo de objeto com.icesoft.faces.env.ServletEnvironment… , ou seja derivados do icefaces. O pior é q eu já tentei armazenar este objeto response, algo q consegu através de um metodo q é chamado no início da página mas quando eu faço uso dele dentro do método para a geração do relatório é como se a página ficasse inativa ai eu dou um refresh no browser e o relatório não é gerado.
Estou tendo fazer uso do myfaces mas na primeira tentativa o meu jboss, pra varia reclamou de alguma coisa, tenho que estudar uma solução que não dispense o Icefaces porque o meu projeto já está muito dependente dele e uma reengenharia seria bem dolorosa.
Muito obrigado pelas dicas
Valeu!!!
Vou tentar resolver com o icefaces e o myfaces

O ice faces é muito interessante, com a tag <ice:commandButton … /> eu não consigo obter o objeto HttpServletResponse devolta mas fazendo uso da tag <ice: outputLink … /> eu consigo obter o tão sonhado objeto HttpServletResponse. Acho q agora vou conseguir resolver meus problemas

muito obrigado pela ajuda :slight_smile:

você tem que chamar o método responseComplete() do facescontext, que senão o que você colocar na resposta não funcionará direito.

:okok: