Sempre Java

agosto 4, 2012

dezembro 4, 2011

Leitura e gravação de imagem em JSF com banco de dados

Olá pessoal, bom dia.
O que me motivou a estar escrevendo esse post foi a dificuldade em encontrar um artigo que descrevesse como gravar imagem no banco de dados
utilizando JSF. Tentei utilizar o componente do primefaces p:graphicImage, porém o mesmo só funciona atrelado a um managed bean com escopo
de sessão, caso contrário, durante o upload a imagem enviada é perdida para uma exibição posterior.
Com isso durante algumas pesquisas, resolvi utilizar o componente do tomahawk, o t:inputFileUpload.
Irei demonstrar a utilização, dividindo o código em três partes, a página JSF, o Validator e o ManagedBean.
Não irei postar aqui a camada de persistência nem a de serviço, pois utilizo injeção de dependências o que caberá a um outro post.
Então vamos lá:

Página JSF (meuPerfil.xhtml):


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:f="http://java.sun.com/jsf/core">

<h:head>

<ui:insert name="title">
<title>Upload de imagem</title>
</ui:insert>

<link href="${facesContext.externalContext.requestContextPath}/resources/css/layout.css" rel="stylesheet"
type="text/css" />
<link href="${facesContext.externalContext.requestContextPath}/resources/css/reset.css" rel="stylesheet"
type="text/css" />

<!--[if IE]>
<link href="${facesContext.externalContext.requestContextPath}/resources/css/ie.css" rel="stylesheet" type="text/css" />
<![endif]-->
<ui:insert name="javascript" />

<ui:insert name="css" />

</h:head>

<h:body onload="loadPage()">
<f:view>
<h:form id="form" prependId="false" enctype="multipart/form-data">

<div id="wrap">

<div id="topo">

<div id="logo">
<h:graphicImage url="/resources/img/logo.png" />
</div>

<div id="nav">
<ul id="menu">
<li>
<h:commandLink value="Home" action="/index?faces-redirect=true" immediate="true">
<f:ajax execute="@this" render="@none"/>
</h:commandLink>
</li>
<li><h:commandLink value="#{msg['menu.minhaConta']}" action="/jsf/users/user/minhaConta.xhtml?faces-redirect=true" rendered="#{usuarioController.exibeUsuarioAutenticado}" /></li>
<li><h:commandLink value="Vestidos" action="vestido.xhtml" immediate="true" /></li>
<li><h:commandLink value="Alianças" action="alianca.xhtml" immediate="true" /></li>
<li><h:commandLink value="Flores" action="flor.xhtml" immediate="true" /></li>
<li><h:commandLink value="Convites" action="convite.xhtml" immediate="true" /></li>
<li><h:commandLink value="Sapatos" action="sapato.xhtml" immediate="true" /></li>
<li><h:commandLink value="Sair" action="sair.xhtml" immediate="true" /></li>
</ul>
</div>

</div>

<div id="content">

<div id="anunciantes">

</div>

<div id="corpo">

<div id="esquerda">

<p:message showDetail="true" showSummary="false" for="fileUpload" />

<div style="margin-top: 10px; text-align: center">

<h:graphicImage id="imgUsurio" value="#{usuarioController.image}" width="140px;" />
<t:inputFileUpload id="fileUpload" value="#{usuarioController.uploadedFile}" accept="*.jpeg, *.png, *.gif, *.jpg" style="display: none;"
onchange="jQuery('#cdlSubmit').click();" validator="#{usuarioValidator.validate}" />
<h:commandButton id="cdlSubmit" action="#{usuarioController.submit}" style="display: none;" />
<h:commandLink type="button" value="Alterar foto" onclick="jQuery('#fileUpload').click();" style="font-size: 10px;" rendered="#{!empty usuarioController.image}">
<f:ajax event="click" execute="@this" />
</h:commandLink>
<h:commandLink type="button" value="Adicionar foto" onclick="jQuery('#fileUpload').click();" style="font-size: 10px;" rendered="#{empty usuarioController.image}">
<f:ajax event="click" execute="@this" />
</h:commandLink>

</div>

</div>

<div id="centro">

<!-- Seu conteúdo do centro -->

</div>

<div id="direita">

<!-- Seu conteúdo da direita -->

</div>

</div>

<div id="footer">
<h:outputLabel style="color: #000000;" value="#{msg['mensagem.rodape']}" />
</div>

</div>

</div>

</h:form>
</f:view>
</h:body>
</html>

O trecho de código acima possui uma implementação onde escondo o botão “upload” padrão do componente t:inputFileUpload, e adiciono
um commmandLink que faz a chamada do botão upload através de javascript.

Managed Bean (UsuarioController.java):


package br.com.pyramides.controller;

import br.com.pyramides.jsf.FacesUtils;
import br.com.pyramides.model.Usuario;
import br.com.pyramides.model.UsuarioImagem;
import br.com.pyramides.util.Constantes;
import br.com.pyramides.util.CriptografaSenha;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.SelectItem;
import javax.imageio.stream.FileImageOutputStream;
import javax.inject.Named;
import javax.servlet.ServletContext;
import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
*
* @author Lessandro
*/

//Caso você não esteja utilizando injeção de dependências, substitua o @Controller pelo @ManagedBean,
//o @Scope("view") pelo @ViewScoped e remova o @Named, pois o nome seria definido da seguinte maneira
//@ManagedBean(name="usuarioController")
@Named("usuarioController")
@Controller
@Scope("view")
public class UsuarioController implements Serializable {

private static final long serialVersionUID = 1L;
private Usuario usuario;
private String mensagem;
private boolean somenteLeitura, exibeUsuarioAutenticado;
private String image;
private UploadedFile uploadedFile;
private static final String EXTENSION = "png";

@PostConstruct
public void init() {
//
// Chamado só quando o managed bean é colocado no escopo view, e não a
// cada requisição como acontecia com o escopo request
//
String currentPage = FacesContext.getCurrentInstance().getViewRoot().getViewId();
if (currentPage.indexOf("meuPerfil.xhtml") != -1) {
preparaUsuario();
geraImagemServidor();
}
}

@PreDestroy
public void destroy() {
//
// chamado quando outra view for chamada através do
// UIViewRoot.setViewId(String viewId)
//
setSomenteLeitura(false);
}

//
// Método que realiza o upload da imagem para a base.  Reparem que tenho o objeto Usuario que está vinculado a um objeto
// UsuarioImagem. O nome da imagem para o objeto UsuarioImagem é o nome do usuário criptografado com MD5 mais a extensão,
// para que eu consiga realizar uma certa segurança, ficando algo como "dsahe37436dahg43rfd4da743743djs.png".
// A foto é um array de bytes, e a extensão é a mesma do arquivo que foi realizado Upload.
// Reparem também que existe uma propriedade setThumbnail, pois a imagem que gero no servidor e na base é um thumbnail, pois
// no meu caso não tenho a necessidade de exibir imagem maiores. Caso não queiram reduzir o tamanho da imagem, basta apenas
// setar a propriedade setFoto() com o array de bytes real.
//
public void submit() {
try {
byte[] bytes = uploadedFile.getBytes();
byte[] thumbBytes = setThumbnail(bytes, EXTENSION);
UsuarioImagem usuarioImagem = usuario.getUsuarioImagem() != null ? usuario.getUsuarioImagem() : new UsuarioImagem();
usuarioImagem.setUsuario(usuario);
String nomeImagem = CriptografaSenha.criptografar(usuario.getNome()) + "." + EXTENSION;
usuarioImagem.setNome(nomeImagem);
usuarioImagem.setFoto(thumbBytes);
usuarioImagem.setExtensao(EXTENSION);
usuario.setUsuarioImagem(usuarioImagem);
usuario.setPassword(getUsuarioAutenticado().getPassword());
// Chama o método "atualizar" do DAO responsável por realizar um "update" na tabela, não disponibilizei aqui por se tratar
//de um DAO já abordado em outros posts.
//
UsuarioDAO usuarioDAO = new UsuarioDAO();
usuarioDAO.atualiza(usuario);
geraImagemServidor();
} catch (Exception ex) {
System.out.println("Erro " + ex.getMessage());
}
}

//
// Método que carrega a imagem vinculada ao objeto usuário, e cria um arquivo com os bytes desta imagem no servidor,
// dentro da pasta resources/img/users, da mesma forma como fiz o upload, o nome da imagem é o nome do usuário criptografado
// com a extensão png.
//
private void geraImagemServidor() {
try {
if (usuario.getUsuarioImagem() != null) {
FacesContext context = FacesContext.getCurrentInstance();
ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
String imageUsers = servletContext.getRealPath("/resources/img/users");
File dirImageUsers = new File(imageUsers);
if (!dirImageUsers.exists()) {
dirImageUsers.createNewFile();
}

byte[] bytes = usuario.getUsuarioImagem().getFoto();
FileImageOutputStream imageOutput = new FileImageOutputStream(new File(dirImageUsers, CriptografaSenha.criptografar(usuario.getNome()) + "." + EXTENSION));
imageOutput.write(bytes, 0, bytes.length);
imageOutput.flush();
imageOutput.close();
setImage("/resources/img/users/" + CriptografaSenha.criptografar(usuario.getNome()) + "." + EXTENSION);
}
} catch (Exception ex) {
System.out.println("Erro " + ex.getMessage());
}
}

//
// Método que seta o usuário através do carregamento do usuário autenticado (este está sendo pego da session)
//
public void preparaUsuario() {
try {
Usuario usuarioAutenticado = getUsuarioAutenticado().clone();
usuarioAutenticado.setPassword(new String());
setUsuario(usuarioAutenticado);
setExibeUsuarioAutenticado(usuarioAutenticado != null ? true : false);
} catch (Exception ex) {
System.out.println("Erro preparação " + ex.getMessage());
}
}

//
// Cria um thumbnail da imagem com largura máxima de 140. A altura é definida pelo cálculo da
// largura de acordo com o tamanho real da imagem, ou seja, ele redimensiona a imagem por igual
//
public byte[] setThumbnail(byte[] arquivo, String extensao) {
ImageIcon imageIcon = new ImageIcon(arquivo);
Image inImage = imageIcon.getImage();
double scale = (double) 140 / (double) inImage.getWidth(null);

int scaledW = (int) (scale * inImage.getWidth(null));
int scaledH = (int) (scale * inImage.getHeight(null));

BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);

AffineTransform tx = new AffineTransform();
if (scale < 1.0d) {
tx.scale(scale, scale);
}

Graphics2D g2d = outImage.createGraphics();
g2d.drawImage(inImage, tx, null);
g2d.dispose();

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(outImage, extensao, baos);
return baos.toByteArray();
} catch (IOException e) {
System.out.println("Error");
} finally {
try {
baos.close();
} catch (IOException e) {
System.out.println("Error");
}
}
return null;
}

public void encerraSessao() {
autenticacaoController.encerraSessao();
}

public Usuario getUsuario() {
return usuario;
}

public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}

public String getMensagem() {
return mensagem;
}

public void setMensagem(String mensagem) {
this.mensagem = mensagem;
}

public void setExibeUsuarioAutenticado(boolean exibeUsuarioAutenticado) {
this.exibeUsuarioAutenticado = exibeUsuarioAutenticado;
}

public boolean isExibeUsuarioAutenticado() {
return exibeUsuarioAutenticado;
}

public boolean isSomenteLeitura() {
return somenteLeitura;
}

public void setSomenteLeitura(boolean somenteLeitura) {
this.somenteLeitura = somenteLeitura;
}

public String getImage() {
return image;
}

public void setImage(String image) {
this.image = image;
}

public UploadedFile getUploadedFile() {
return uploadedFile;
}

public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}

public Usuario getUsuarioAutenticado() {
FacesContext ctx = FacesContext.getCurrentInstance();
session = (HttpSession) ctx.getExternalContext().getSession(false);
if (session != null) {
usuarioAutenticado = (Usuario) session.getAttribute("usuarioAutenticado");
}
return usuarioAutenticado;
}
}

Pronto, seu ManagedBean está criado, possibilitando realizar o upload da imagem, gravando na base, e posteriormente sendo
recuperada e gerada no servidor.

Agora segue o validator onde limito o tamanho da imagem que o usuário pode enviar para o servidor, evitando assim que o usuário
sobrecarregue o servidor fazendo chamadas desnecessárias.

UsuarioValidator.java


package br.com.pyramides.validator;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.inject.Named;
import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
*
* @author Lessandro
*/

// Aqui fica a mesma ideia abordada anteriormente no ManagedBean quando utilza ou não injeção de dependências
@Named("usuarioValidator")
@Controller
@Scope("view")
public class UsuarioValidator {

private static final long MAX_FILE_SIZE = 200000; // 200KB

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (((UploadedFile) value).getSize() > MAX_FILE_SIZE) {
FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, new String(), "O arquivo deve ter no máximo 200KB.");
FacesContext.getCurrentInstance().addMessage("iphFileUpload", facesMsg);
throw new ValidatorException(facesMsg);
}
}
}

Pronto, o envio de imagens para o servidor está concluído, espero que tenha ajudado.
Qualquer dúvida basta enviá-la que na medida do possível estarei respondendo.
Abs

janeiro 6, 2011

Aplicação integrando JSF 2.0 + Spring 3 + Maven 2

Filed under: Desenvolvimento Web — Tags:, , , , , , , , , , , — semprejava @ 10:34 am

Olá pessoal.
Acabo de colocar no github a APP que gerei aqui integrando os 3 frameowrks, JSF 2.0, Spring 3 e Maven 2.
O endereço é esse: GitHub AutoPecas
Em breve estarei disponibilizando a integração com o Spring Security.
A aplicação é bem trivial, apenas com cadastro de Perfil e Usuário, porém pode ser utilizada como
modelo para a criação de uma aplicação profissional utilizando essa gama de frameworks que permitem uma melhor produtividade.
Fiquem atentos, pois o repositório está sob constante atualização e em breve estarei postando essa nova integração.
Futuramente estarei criando um Post explicando como criar a aplicação passo a passo.
Ah, outro detalhe, juntamente com a aplicação, no pacote “Util” temos o script autopecas.sql que irá gerar um perfil e um usuário para acesso ao sistema.
Abraços e até a próxima,
Lessandro

agosto 21, 2010

Gerar uma lib para reutilização em projetos

Filed under: Desenvolvimento Web — Tags:, , , — semprejava @ 10:10 pm

Fala pessoal, boa noite.
Irei demonstrar como gerar uma lib apenas para utilização em mais de um projeto. Por exemplo, se você tem um projeto web e um desktop, sendo que estes utilizam as mesmas libs e até mesmo implementam classes modelo e “managed beans” contendo as mesmas regras de negócio, data access objects, ou seja, tudo que pode ser reutilizado.

Então faremos o seguinte. Criamos um projeto de biblioteca. Novo Projeto -> Java -> Biblioteca para classe Java.

No projeto, em biblioteca, adicione as libs necessárias. Crie normalmente também as classes modelo, os managed Beans, os Data Access Objects, sendo que o contexto seja compatível com ambas as arquiteturas.
Com isso a camada de visão e algo particular para ambas as arquiteturas serão implementadas nestas.

Agora vá no arquivo build.xml e deixe-o similar à configuração abaixo:

<!-- Nome do projeto teste, basedir = raiz, nome da ação = executar -->
<project name="teste" basedir="." default="executar">
    <property name="classes" location="classes"/>

    <target name="dir">
        <mkdir dir="classes" />
    </target>

    <!-- Nome da opção no menu de contexto = limpar, remove as classes compiladas -->
    <target name="limpar">
        <delete dir="classes"/>
    </target>

   <!-- Nome da opção no menu de contexto = compilar  -->
    <target name="compilar" depends="dir"> 
        <javac srcdir="${basedir}"
        classpath="${classes}"
        destdir="${classes}" />
    </target>

    <!-- Nome da opção no menu de contexto = empacotar para gerar o jar único -->
    <target name="empacotar" depends="compilar">
        <!-- Caminho contendo as bibliotecas para empacotar -->
        <mkdir dir="build/jar"/>
        <!-- Caminho para gerar a biblioteca empacotada e o nome do jar -->
        <jar destfile="build/jar/Empresa.jar"
            <!-- Incluir também as classes compiladas -->
             basedir="${basedir}/classes">
            <manifest>
                <!-- Nome da classe principal -->
                <attribute name="Main-Class" value="Empresa"/>
            </manifest>
        </jar>
    </target>

    <!-- Nome da opção no menu de contexto = executar, executa o jar compilado -->
    <target name="executar" depends="empacotar, limpar">
        <java jar="build/jar/Empresa.jar" fork="true"/>
    </target>
</project>

Com isso, ao clicar com o botão direito sob o arquivo build.xml, este lhe fornecerá as opções mencionadas acima, gerando um único jar, para ser acoplado ao sistema desejado.
Isso me ajudou muito ao desenvolver um sistema web e mobile que utilizavam as mesmas regras de negócio e posteriormente acessavam webservices.
Espero ter ajudado,
Abs,
Lessandro

agosto 16, 2010

Apresentando mensagem após submissão do form no JSF 2.0 com PrimeFaces

Filed under: Desenvolvimento Web — Tags:, , , — semprejava @ 6:17 pm

Olá pessoal, boa noite.
Estarei aqui demonstrando como exibir a mensagem de sucesso ou erro após a submissão do form no JSF 2.0 com o Primefaces 2.1.

Primeiro temos a página xhtml, onde possuímos um p:dialog que ficará responsável por exibir a mensagem que o Managed Bean retornar durante a persistência de determinado objeto na base.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <ui:composition template="/resources/template.xhtml">

        <ui:define name="login">
            <ui:include src="/resources/usuarioAutenticado.xhtml" />
        </ui:define>

        <ui:define name="javascript">
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery.maskedinput-1.2.2.js"></script>
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery-1.4.2.js"></script>
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/funcoes.js"></script>
        </ui:define>

        <ui:define name="centro">

            <p:outputPanel id="oplDialog" layout="block">
                <p:dialog id="dlgMsg" header="#{msg['modalPanel.msgAlerta']}"
                          position="center" minWidth="300" width="300" visible="true"
                          resizable="false" modal="true" rendered="#{perfilController.exibeDialog}">
                    <h:panelGrid columns="1" cellspacing="5px">
                        <h:outputLabel id="oplMensagem" value="#{perfilController.mensagem}" styleClass="fonteAlerta" />
                        <h:commandButton id="cbtOk" value="#{msg['botao.ok']}"
                                         action="/jsf/perfil/exibirPerfis?faces-redirect=true" immediate="true">
                        </h:commandButton>
                    </h:panelGrid>
                </p:dialog>
            </p:outputPanel>

            <p:outputPanel id="pnlCentro" layout="block" style="position: relative; margin: auto; margin-top: 30px; width: 900px;">
				<p:panel id="pnlCorpoPerfil" style="position: relative; margin: auto; margin-top: 20px; width: 900px;"
						 rendered="#{!perfilController.exibeListaPerfis}">
					<f:facet name="header">
						<h:outputText value="#{msg['perfil.detalhe']}" />
					</f:facet>

					<h:panelGrid id="pgrPerfil" columns="3">

						<h:outputLabel value="*" styleClass="fonteAlerta">
							<h:outputLabel styleClass="fontePadrao" value="#{msg['perfil.nome']}" />
						</h:outputLabel>
						<h:inputText id="iptNome" value="#{perfilController.perfil.nmPerfil}" size="21" maxlength="20"
									 onkeyup="this.value = somenteCaracteres(this.value)" required="true" requiredMessage="#{msg['perfil.nome.requerido']}"
									 readonly="#{perfilController.somenteLeitura}" />
						<h:message for="iptNome" styleClass="fonteAlerta" showDetail="true" showSummary="false" />

						<h:outputLabel value="*" styleClass="fonteAlerta">
							<h:outputLabel styleClass="fontePadrao" value="#{msg['perfil.descricao']}" />
						</h:outputLabel>
						<h:inputText id="iptDescricao" value="#{perfilController.perfil.dsPerfil}" size="61" maxlength="60"
									 onkeyup="this.value = somenteCaracteres(this.value)"
									 required="true" requiredMessage="#{msg['perfil.descricao.requerido']}"
									 readonly="#{perfilController.somenteLeitura}" />
						<h:message for="iptDescricao" styleClass="fonteAlerta" showDetail="true" showSummary="false" />

					</h:panelGrid>

					<f:facet name="footer">
						<p:commandButton  value="#{msg['botao.fechar']}"
										  action="/jsf/perfil/exibirPerfis?faces-redirect=true"
										  immediate="true" />
						<h:outputText value=" " />
						<p:commandButton  id="cbtIncluir" value="#{msg['botao.incluir']}"
										  rendered="#{perfilController.exibeBotaoIncluir}" actionListener="#{perfilController.salvar}"
										  update="pgrPerfil, oplDialog" />
						<p:commandButton  id="cbtAlterar" value="#{msg['botao.alterar']}"
										  rendered="#{perfilController.exibeBotaoAlterar}" actionListener="#{perfilController.alterar}"
										  update="pgrPerfil, oplDialog" />
						<p:commandButton  id="cbtExcluir" value="#{msg['botao.excluir']}"
										  rendered="#{perfilController.exibeBotaoExcluir}" actionListener="#{perfilController.excluir}"
										  update="pgrPerfil, oplDialog" />
					</f:facet>
				</p:panel>
            </p:outputPanel>
        </ui:define>

    </ui:composition>
</html>

Reparem que o dialog da mensagem possui um rendered que a princípio sua exibição é falsa. Dentro desse dialog temos um label que está setado num atributo do Managed Beans e este será alterado em tempo de execução. Ao submetermos o form através da ação do botão de incluir por exemplo no Managed Beans, mandamos atualizar o componente outoutPanel com o id “oplDialog”. Estou também atualizando o painelGrid por outro motivo, mas não se atentem para essa questão.
Segue abaixo agora o Managed Bean, o qual manipulamos o DAO responsável por incluir, alterar, excluir e consultar um Perfil. Atentem-se para a mensagem que é alterada e o atributo booleano de exibição do dialog.

package br.com.notaroberto.controller;

import br.com.notaroberto.dao.PerfilDAO;
import br.com.notaroberto.model.Perfil;
import java.io.Serializable;
import java.util.List;
import java.util.ResourceBundle;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.event.ActionEvent;

@ManagedBean(name = "perfilController")
@ViewScoped
public class PerfilController implements Serializable {

	private static final long serialVersionUID = 398906636209328367L;
	private Perfil perfil;
    private PerfilDAO perfilDAO;
    private List<Perfil> listaPerfis;
    private String mensagem;
    private boolean exibeBotaoIncluir, exibeBotaoAlterar,
            exibeBotaoExcluir, somenteLeitura,
            exibeListaPerfis = true, exibeDialog;

    @PostConstruct
    public void init() {
        // Chamado só quando o managed bean é colocado no escopo view,
        // e não a cada requisição como acontecia com o escopo request
        perfilDAO = new PerfilDAO();
        setListaPerfis(perfilDAO.buscaTodos());
    }

    @PreDestroy
    public void destroy() {
        /* chamado quando outra view for chamada através do UIViewRoot.setViewId(String viewId) */
        setListaPerfis(null);
        setExibeBotaoIncluir(false);
        setExibeBotaoAlterar(false);
        setExibeBotaoExcluir(false);
        setExibeListaPerfis(true);
        setSomenteLeitura(false);
    }

    public Perfil getPerfil() {
        return perfil;
    }

    public void setPerfil(Perfil perfil) {
        this.perfil = perfil;
    }

    public List<Perfil> getListaPerfis() {
        return listaPerfis;
    }

    public void setListaPerfis(List<Perfil> listaPerfis) {
        this.listaPerfis = listaPerfis;
    }

    public String getMensagem() {
        return mensagem;
    }

    public void setMensagem(String mensagem) {
        this.mensagem = mensagem;
    }

    public boolean isExibeBotaoIncluir() {
        return exibeBotaoIncluir;
    }

    public void setExibeBotaoIncluir(boolean exibeBotaoIncluir) {
        this.exibeBotaoIncluir = exibeBotaoIncluir;
    }

    public boolean isExibeBotaoAlterar() {
        return exibeBotaoAlterar;
    }

    public void setExibeBotaoAlterar(boolean exibeBotaoAlterar) {
        this.exibeBotaoAlterar = exibeBotaoAlterar;
    }

    public boolean isExibeBotaoExcluir() {
        return exibeBotaoExcluir;
    }

    public void setExibeBotaoExcluir(boolean exibeBotaoExcluir) {
        this.exibeBotaoExcluir = exibeBotaoExcluir;
    }

    public boolean isSomenteLeitura() {
        return somenteLeitura;
    }

    public void setSomenteLeitura(boolean somenteLeitura) {
        this.somenteLeitura = somenteLeitura;
    }

    public boolean isExibeListaPerfis() {
        return exibeListaPerfis;
    }

    public void setExibeListaPerfis(boolean exibeListaPerfis) {
        this.exibeListaPerfis = exibeListaPerfis;
    }

    public boolean isExibeDialog() {
        return exibeDialog;
    }

    public void setExibeDialog(boolean exibeDialog) {
        this.exibeDialog = exibeDialog;
    }

    public void preparaInclusao() {
        perfil = new Perfil();
        setExibeListaPerfis(false);
        setExibeBotaoIncluir(true);
    }

    public void preparaConsulta() {
        setExibeListaPerfis(false);
        setSomenteLeitura(true);
    }

    public void preparaAlteracao() {
        setExibeListaPerfis(false);
        setSomenteLeitura(false);
        setExibeBotaoAlterar(true);
    }

    public void preparaExclusao() {
        setExibeListaPerfis(false);
        setSomenteLeitura(true);
        setExibeBotaoExcluir(true);
    }

    public void carregaPerfisUsuarios() {
        perfilDAO = new PerfilDAO();
        setListaPerfis(perfilDAO.buscaTodos());
    }

    public void salvar(ActionEvent actionEvent) {
        setExibeDialog(false);
        try {
            perfilDAO = new PerfilDAO();
            perfilDAO.salva(perfil);
            setExibeDialog(true);
            setMensagem(ResourceBundle.getBundle("/message").getString("perfil.criadoSucesso"));
        } catch (Exception e) {
            setExibeDialog(true);
            setMensagem(e + " " + ResourceBundle.getBundle("/message").getString("perfil.erroIncluir"));
        }
    }

    public void alterar(ActionEvent actionEvent) {
        setExibeDialog(false);
        try {
            perfilDAO = new PerfilDAO();
            perfilDAO.altera(perfil);
            setExibeDialog(true);
            setMensagem(ResourceBundle.getBundle("/message").getString("perfil.alteradoSucesso"));
        } catch (Exception e) {
            setExibeDialog(true);
            setMensagem(e + " " + ResourceBundle.getBundle("/message").getString("perfil.erroAlterar"));
        }
    }

    public void excluir(ActionEvent actionEvent) {
        setExibeDialog(false);
        try {
            perfilDAO = new PerfilDAO();
            perfilDAO.exclui(perfil);
            setExibeDialog(true);
            setMensagem(ResourceBundle.getBundle("/message").getString("perfil.excluidoSucesso"));
        } catch (Exception e) {
            setExibeDialog(true);
            setMensagem(e + " " + ResourceBundle.getBundle("/message").getString("perfil.erroExcluir"));
        }
    }

    @FacesConverter(forClass = Perfil.class, value = "perfilConverter")
    public static class PerfilControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if ((value == null) || (value.length() == 0)) {
                return null;
            }

            PerfilController perfilController = (PerfilController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(),
                    null, "perfilController");

            return perfilController.perfilDAO.buscaPeloID(getID(value));
        }

        Integer getID(String value) {
            Integer id;
            id = Integer.valueOf(value);
            return id;
        }

        String getStringID(Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }

            if (object instanceof Perfil) {
                Perfil p = (Perfil) object;

                return getStringID(p.getIdPerfil());
            } else {
                throw new IllegalArgumentException("objeto " + object + " possui o tipo " + object.getClass().getName()
                        + "; tipo esperado: " + PerfilController.class.getName());
            }
        }
    }
}

Evitei de usar javascript para exibição do dialog, conforme alguns utilizam, pois já tive problemas com esse tipo de modelo (dlg.show()). O primefaces implementa a utilização do dialog de forma diferente, onde é verificado se ocorreu algum erro no Managed Beans e depois o show é executado dentro de um método javascript, onde tem algo como if (!validation.args).
Grande abraço,
Até o próximo post,
Lessandro

Exportando relatorio iReport/Jasper para PDF

Filed under: Desenvolvimento Web — Tags:, , , , — semprejava @ 2:18 pm

Olá pessoal, boa tarde.
Estou novamente por aqui, dessa vez para publicar como exportar o relatório gerado no iReport para PDF.
Primeiramente deveremos ter as seguintes libs em nossa app (WEB-INF/lib):

iText-2.1.0.jar
jasperreports-3.7.4.jar
jasperreports-applet-3.7.4.jar
jasperreports-fonts-3.7.4.jar
jasperreports-javaflow-3.7.4.jar
poi-3.0.1-FINAL.jar
commons-beanutils-1.8.3.jar
commons-collections-2.1.1.jar
commons-javaflow-20060411.jar
commons-logging-1.1.1.jar
commons-logging-api-1.1.1.jar

Algumas libs não são obrigatórias, mas coloquei-as para evitar erros posteriores.

Abaixo o XHTML reponsável por invocar o Managed Bean e preencher a query desejada. No meu caso trata-se de um relatório de pedidos do cliente, onde usuário poderá informar o nome do cliente, data início e data fim, ou pode simplesmente não preencher o filtro.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <ui:composition template="/resources/template.xhtml">

        <ui:define name="login">
            <ui:include src="/resources/usuarioAutenticado.xhtml" />
        </ui:define>

        <ui:define name="javascript">
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery.maskedinput-1.2.2.js"></script>
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/jquery.validate.js"></script>
            <script type="text/javascript" src="${facesContext.externalContext.requestContextPath}/js/funcoes.js"></script>
        </ui:define>

        <ui:define name="centro">

            <p:messages />

            <p:outputPanel id="oplDialog" layout="block">
                <p:dialog id="dlgMsg" header="#{msg['modalPanel.msgAlerta']}"
                          position="center" minWidth="300" width="300" visible="true"
                          resizable="false" modal="true" rendered="#{relatorioPedidosClienteController.exibeDialog}">
                    <h:panelGrid columns="1" cellspacing="5px">
                        <h:outputLabel id="oplMensagem" value="#{relatorioPedidosClienteController.mensagem}" styleClass="fonteAlerta" />
                        <p:commandButton  id="cbtOk" value="#{msg['botao.ok']}" action="/index?faces-redirect=true" immediate="true" />
                    </h:panelGrid>
                </p:dialog>
            </p:outputPanel>

            <p:panel id="pnlCorpoRelatorioCliente" style="position: relative; margin: auto; margin-top: 20px; width: 900px;">
                <f:facet name="header">
                    <h:outputText value="Detalhes do Relatório de Pedidos do Cliente" />
                </f:facet>

                <h:panelGrid columns="3" columnClasses="col1, col2, col3">
                    <h:outputLabel styleClass="fontePadrao" value="#{msg['pedido.cliente.nome']}" />
                    <h:inputText id="iptNomeClientePesq" size="70" maxlength="100"
                                 onkeyup="this.value = somenteCaracteres(this.value)"
                                 value="#{relatorioPedidosClienteController.cliente.nmCliente}" />
                    <p:commandButton  value="Pesquisar" action="#{relatorioPedidosClienteController.carregaClientesPeloNome}"
                                      update="tabClientes" />
                </h:panelGrid>

                <p:outputPanel layout="block">
                    <p:dataTable id="tabClientes" value="#{relatorioPedidosClienteController.listaClientes}" var="cliente" rows="3"
                                 width="700px" emptyMessage="#{msg['tabela.nenhumRegistroEncontrado']}" paginator="true"
                                 paginatorPosition="bottom" style="position: relative; margin: auto; text-decoration: none; font-size: 12px;"
                                 firstPageLinkLabel="#{msg['tabela.primeiroRegistro']}" nextPageLinkLabel="#{msg['tabela.proximoRegistro']}"
                                 previousPageLinkLabel="#{msg['tabela.anteriorRegistro']}" lastPageLinkLabel="#{msg['tabela.ultimoRegistro']}"
                                 selectionMode="single">
                        <p:column>
                            <f:facet name="header">
                                <h:outputText value="#{msg['cliente.tabela.cpf']}" />
                            </f:facet>
                            <h:outputText value="#{cliente.nuCpf}" />
                        </p:column>
                        <p:column>
                            <f:facet name="header">
                                <h:outputText value="#{msg['cliente.tabela.cnpj']}" />
                            </f:facet>
                            <h:outputText value="#{cliente.nuCnpj}" />
                        </p:column>
                        <p:column sortBy="#{cliente.nmCliente}">
                            <f:facet name="header">
                                <h:outputText value="#{msg['cliente.tabela.nome']}" />
                            </f:facet>
                            <h:outputText value="#{cliente.nmCliente}" />
                        </p:column>
                        <p:column>
                            <f:facet name="header">
                                <h:outputText value="#{msg['cliente.tabela.cep']}" />
                            </f:facet>
                            <h:outputText value="#{cliente.nuCep}" />
                        </p:column>
                        <p:column>
                            <p:commandLink id="cdlSelecionaCliente" update="iptNomeClientePesq">
                                <h:graphicImage url="/img/tick.png" title="#{msg['botao.consultar']}" />
                                <f:setPropertyActionListener value="#{cliente}" target="#{relatorioPedidosClienteController.cliente}" />
                            </p:commandLink>
                        </p:column>
                    </p:dataTable>
                </p:outputPanel>

                <h:panelGrid columns="2" columnClasses="col1, col2">
                    <h:outputLabel styleClass="fontePadrao" value="Data Inicial:" />
                    <p:inputMask id="iptDataEmissao" mask="99/99/9999" maxlength="10" size="11" value="#{relatorioPedidosClienteController.dataInicio}">
                        <f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{relatorioPedidosClienteController.timeZone}" />
                    </p:inputMask>

                    <h:outputLabel styleClass="fontePadrao" value="Data Final:" />
                    <p:inputMask id="iptDataVencimento" mask="99/99/9999" maxlength="10" size="11" value="#{relatorioPedidosClienteController.dataFim}">
                        <f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{relatorioPedidosClienteController.timeZone}" />
                    </p:inputMask>
                </h:panelGrid>

                <f:facet name="footer">
                    <p:commandButton  value="#{msg['botao.fechar']}" action="/index?faces-redirect=true"
                                      immediate="true" />
                    <h:outputText value=" " />
                    <p:commandButton  id="cbtGerarRelatorio" value="Gerar Relatório" action="#{relatorioPedidosClienteController.geraRelatorio}"
                                      ajax="false" >
                        <p:ajax event="complete" update="oplDialog" />
                    </p:commandButton>

                </f:facet>
            </p:panel>

        </ui:define>
    </ui:composition>
</html>

Agora o ManagedBean responsável por passar os parâmetros para o relatório (arquivo .jasper) gerado durante a compilação do mesmo, e exportá-lo para pdf.

package br.com.notaroberto.controller;

import br.com.notaroberto.model.Cliente;
import br.com.notaroberto.util.Funcoes;
import br.com.notaroberto.util.HibernateUtil;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.TimeZone;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;

@ManagedBean(name = "relatorioPedidosClienteController")
@ViewScoped
public class RelatorioPedidosClienteController {

    private TimeZone timeZone = TimeZone.getDefault();
    private JasperPrint impressao;
    private HashMap<String, Serializable> parametroMap;
    private FacesContext context;
    private ServletContext servletContext;
    private String mensagem, caminhoRelatorio;
    private Date dataInicio, dataFim;
    private boolean exibeDialog, exibeTabelaCliente;
    private Cliente cliente;
    private List<Cliente> listaClientes;

    @PostConstruct
    public void init() {
        // Chamando ao instanciar o escopo de visao 
        cliente = new Cliente();
    }

    @PreDestroy
    public void destroy() {
        // A chamada eh realizada quando a pagina eh alterada 
    }

    public String getMensagem() {
        return mensagem;
    }

    public void setMensagem(String mensagem) {
        this.mensagem = mensagem;
    }

    public boolean isExibeDialog() {
        return exibeDialog;
    }

    public void setExibeDialog(boolean exibeDialog) {
        this.exibeDialog = exibeDialog;
    }

    public boolean isExibeTabelaCliente() {
        return exibeTabelaCliente;
    }

    public void setExibeTabelaCliente(boolean exibeTabelaCliente) {
        this.exibeTabelaCliente = exibeTabelaCliente;
    }

    public Date getDataInicio() {
        return dataInicio;
    }

    public void setDataInicio(Date dataInicio) {
        this.dataInicio = dataInicio;
    }

    public Date getDataFim() {
        return dataFim;
    }

    public void setDataFim(Date dataFim) {
        this.dataFim = dataFim;
    }

    public TimeZone getTimeZone() {
        return timeZone;
    }

    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    public List<Cliente> getListaClientes() {
        return listaClientes;
    }

    public void setListaClientes(List<Cliente> listaClientes) {
        this.listaClientes = listaClientes;
    }

    public void carregaClientesPeloNome() {
        ClienteController clienteController = new ClienteController();
        clienteController.carregaClientesPeloNome(cliente.getNmCliente());
        setListaClientes(clienteController.getListaClientes());
    }

    public String montaSQL(Integer idCliente, String dataInicio, String dataFim) {
        String sql = " 1 = 1";

        if (!dataInicio.isEmpty() && !dataFim.isEmpty()) {
            sql += " AND ( ped.DATA_EMISSAO BETWEEN STR_TO_DATE('" + dataInicio + "', '%d/%m/%Y') AND STR_TO_DATE('" + dataFim + "', '%d/%m/%Y') )";
        }

        if (idCliente != null) {
            sql += " AND cli.ID_CLIENTE = '" + idCliente + "'";
        }

        sql += " GROUP BY cli.ID_CLIENTE, ped.ID_PEDIDO, prod.ID_PRODUTO, pp.ID_PED_PROD";

        return sql;
    }

    public void geraRelatorio() {
        context = FacesContext.getCurrentInstance();
        servletContext = (ServletContext) context.getExternalContext().getContext();

        caminhoRelatorio = servletContext.getRealPath("/relatorios/jasper/RelatorioPedidosCliente.jasper");
        mensagem += "Caminho do relatório: " + caminhoRelatorio + "\n ";

        mensagem += "Sistema Operacional: " + Funcoes.retornaSistemaOperacional().toLowerCase() + "\n ";

        parametroMap = new HashMap<String, Serializable>();
        String sql = montaSQL(cliente.getIdCliente(),
                dataInicio != null ? Funcoes.formataDataEmString(dataInicio) : "",
                dataFim != null ? Funcoes.formataDataEmString(dataFim) : "");
        parametroMap.put("sql", sql);

        /* criando novo cliente apos passagem de parametro para nova pesquisa */
        cliente = new Cliente();
        String dataIni = dataInicio != null ? Funcoes.formataDataEmString(dataInicio) : "00/00/0000";
        String dataF = dataFim != null ? Funcoes.formataDataEmString(dataFim) : "00/00/0000";
        String periodo = "Período de: " + dataIni + " a " + dataF;
        parametroMap.put("periodo", periodo);
        setExibeDialog(true);
        enviarPdf();
    }

    public void enviarPdf() {
        // Carrega o xml de definição do relatório
        try {
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
            // Configura o response para suportar o relatório
            response.setContentType("application/pdf");
            // response.addHeader("Content-disposition", "inline; filename=\"arquivo.pdf\"");
            response.addHeader("Content-disposition", "attachment; filename=\"arquivo.pdf\"");

            // Preenche o relatório com os parametros e o data source
            impressao = JasperFillManager.fillReport(caminhoRelatorio, parametroMap, HibernateUtil.recuperaConexao());
            // Exporta o relatório
            JasperExportManager.exportReportToPdfStream(impressao, response.getOutputStream());
            // Salva o estado da aplicação no contexto do JSF
            context.getApplication().getStateManager().saveView(context);
            // Fecha o stream do response
            context.responseComplete();
        } catch (Exception e) {
            setExibeDialog(true);
            mensagem += e;
        }
    }
}

Espero ter ajudado. Tive vários problemas para geração de relatórios em PDF, e pesquisando aqui e ali fui reunindo as informações e consegui montar algo que realmente funcionasse.
Abs,
Lessandro

agosto 11, 2010

Resolvendo o problema de Sessão Expirada

Filed under: Desenvolvimento Web — Tags:, , , , — semprejava @ 10:59 pm

Olá amigos, boa noite.
Depois de alguns dias enrolado com algumas atualizações do meu sistema e resolvendo outras coisas pessoais, estou de volta. Dessa vez para demonstrar uma forma para resolver o problema quando a sessão expira. Muito de vocês já devem ter se deparado com esse tipo de problema. Ao deixar o sistema aberto por um determinado tempo configurado no web.xml, ao chamar alguma action o sistema simplesmente exibe uma mensagem semelhante à essa:

"javax.servlet.ServletException: viewId:/login.faces - View /login.faces could not be restored. javax.faces.webapp.FacesServlet.service(FacesServlet.java:249)"

Setando tempo no web.xml

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

Esse problema é ainda mais difícil resolver quando utilizado o componente Primefaces. Não foi tão trivial assim reunir algumas informações na internet e colocar realmente funcionando.

Para resolver esse tipo de problema, começamos criando um exception-handler-factory no faces-config.xml.

    <factory>
        <exception-handler-factory>caminhodaClasse.ViewExpiredExceptionExceptionHandlerFactory</exception-handler-factory>
    </factory>

Agora vamos criar duas classes para controle dos exceptions de visão:

Classe ViewExpiredExceptionExceptionHandler.java

package br.com.notaroberto.control;

import java.io.IOException;
import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.application.ViewExpiredException;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.RenderKit;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpSession;
import org.primefaces.component.PartialViewRoot;
import org.primefaces.context.RequestContextImpl;
import org.primefaces.context.RequestContext;
import org.primefaces.util.Constants;

public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    public ViewExpiredExceptionExceptionHandler() {
    }

    public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.wrapped;
    }

    @Override
    public void handle() throws FacesException {
        String redirectPage = null;
        for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
            Throwable t = context.getException();
            if (t instanceof ViewExpiredException) {
                ViewExpiredException vee = (ViewExpiredException) t;
                FacesContext fc = FacesContext.getCurrentInstance();
                HttpSession session = (HttpSession) fc.getExternalContext().getSession(true);
                try {
                    // Push some useful stuff to the request scope for use in the page
                    session.setAttribute("currentViewId", vee.getViewId());
                    // Para qual página será redirecionada caso a sessão expire, no meu caso retorna à principal
                    redirectPage = "/app/index.xhtml";
                } finally {
                    i.remove();
                }
                // Redireciona a página
                doRedirect(fc, redirectPage);
                // Importante, colocar a variável de controle exibeDialog na sessão para posteriormente ser     capturada nos managedBean e ser exibido um dialog na respectiva página xhtml.
                session.setAttribute("exibeDialog", true);
            }
        }

        // At this point, the queue will not contain any ViewExpiredEvents.
        // Therefore, let the parent handle them.
        getWrapped().handle();
    }

    public void doRedirect(FacesContext fc, String redirectPage) throws FacesException {
        ExternalContext ec = fc.getExternalContext();

        try {

            // workaround for PrimeFaces
            new RequestContextImpl(ec);
            if (ec.getRequestParameterMap().containsKey(Constants.PARTIAL_PROCESS_PARAM) && !ec.getRequestParameterMap().get(Constants.PARTIAL_PROCESS_PARAM).equals("@all")) {
                fc.setViewRoot(new PartialViewRoot(new UIViewRoot()));
            }

            // fix for renderer kit (Mojarra's and PrimeFaces's ajax redirect)
            if ((RequestContext.getCurrentInstance().isAjaxRequest() || fc.getPartialViewContext().isPartialRequest()) && fc.getResponseWriter() == null && fc.getRenderKit() == null) {
                ServletResponse response = (ServletResponse) ec.getResponse();
                ServletRequest request = (ServletRequest) ec.getRequest();
                response.setCharacterEncoding(request.getCharacterEncoding());

                RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
                RenderKit renderKit = factory.getRenderKit(fc, fc.getApplication().getViewHandler().calculateRenderKitId(fc));
                ResponseWriter responseWriter = renderKit.createResponseWriter(response.getWriter(), null, request.getCharacterEncoding());
                fc.setResponseWriter(responseWriter);
            }
            ec.redirect(ec.getRequestContextPath() + (redirectPage != null ? redirectPage : ""));
        } catch (IOException e) {
            System.out.println("Redirect to the specified page '" + redirectPage + "' failed");
            throw new FacesException(e);
        }
    }
}

Classe ViewExpiredExceptionExceptionHandlerFactory.java

package br.com.notaroberto.control;

import javax.faces.context.ExceptionHandlerFactory;
import javax.faces.context.ExceptionHandler;

public class ViewExpiredExceptionExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    public ViewExpiredExceptionExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        ExceptionHandler result = parent.getExceptionHandler();
        result = new ViewExpiredExceptionExceptionHandler(result);
        return result;
    }
}

Como configuramos na classe acima, caso ocorra alguma exceção na visão, é redirecionada para a página index, e esta está linkada ao ManagedBean AutenticacaoController.java, segue o trecho da mesma abaixo:

package br.com.notaroberto.controller;

import br.com.notaroberto.dao.UsuarioDAO;
import br.com.notaroberto.model.Usuario;
import br.com.notaroberto.util.Constantes;
import br.com.notaroberto.util.JsfUtil;
import java.io.Serializable;
import java.util.ResourceBundle;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 *
 * @author Lessandro
 */
@ManagedBean(name = "autenticacaoController")
@ViewScoped
public class AutenticacaoController implements Serializable {

    private static final long serialVersionUID = 483391080902399125L;
    private Usuario usuario, usuarioAutenticado;
    private UsuarioDAO usuarioDAO;
    // Variavel responsavel por fazer o controle se será exibido o dialog que a sessao expirou
    private boolean exibeDialog;
    private HttpSession session;

    @PostConstruct
    public void init() {
        /* Chamado só quando o managed bean é colocado no escopo view,
        e não a cada requisição como acontecia com o escopo request */
        usuario = new Usuario();
    }

    @PreDestroy
    public void destroy() {
        /* chamado quando outra view for chamada através do UIViewRoot.setViewId(String viewId) */
    }

    public Usuario getUsuario() {
        return usuario;
    }

    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    public Usuario getUsuarioAutenticado() {
        recuperaSessao();
        if (session.getAttribute("usuarioAutenticado") != null) {
            usuarioAutenticado = (Usuario) session.getAttribute("usuarioAutenticado");
        }
        return usuarioAutenticado;
    }

    public void setUsuarioAutenticado(Usuario usuarioAutenticado) {
        this.usuarioAutenticado = usuarioAutenticado;
    }

    // get linkado à uma tag rendered na pagina index.xhtml, responsável por capturar a variável colocada na sessão na classe ViewExpiredExceptionExceptionHandler e caso tenha recebido valor true, exibe o dialog que a sessão expirou
    public boolean isExibeDialog() {
        recuperaSessao();
        if (session.getAttribute("exibeDialog") != null) {
            exibeDialog = (Boolean) session.getAttribute("exibeDialog");
        }
        return exibeDialog;
    }

    public void setExibeDialog(boolean exibeDialog) {
        this.exibeDialog = exibeDialog;
    }

    public String autenticaUsuario() {
        try {
            usuarioDAO = new UsuarioDAO();
            usuarioAutenticado = usuarioDAO.buscaLoginSenha(usuario.getDsLogin(), usuario.getDsSenha());
            if (usuarioAutenticado == null) {
                JsfUtil.addErrorMessage("iphMensagem", ResourceBundle.getBundle("/message").getString("usuario.naoEncontrado"));
            } else {
                FacesContext ctx = FacesContext.getCurrentInstance();
                session = (HttpSession) ctx.getExternalContext().getSession(false);
                session.setAttribute("usuarioAutenticado", usuarioAutenticado);
                System.out.println(session.getId());
                return Constantes.URL_MENU_HOME;
            }
        } catch (Exception e) {
            JsfUtil.addErrorMessage("iphMensagem", ResourceBundle.getBundle("/message").getString("mensagem.conexao.erro"));
        }
        return "";
    }

    public void encerraSessao() {
        try {
            FacesContext ctx = FacesContext.getCurrentInstance();
            session = (HttpSession) ctx.getExternalContext().getSession(false);
            session.setAttribute("usuarioAutenticado", null);
            ctx.getExternalContext().redirect(ctx.getExternalContext().getRequestContextPath() + "/app" + Constantes.PAGINA_INDEX);
            session.invalidate();
        } catch (Exception e) {
        }
    }

    public void recuperaSessao() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
        session = request.getSession();
    }

    public void fechaModal() {
        recuperaSessao();
        session.setAttribute("exibeDialog", false);
    }
}

Agora um fragmento da página index com a tag responsável por renderizar ou não o dialog que exibe a mensagem que a sessão expirou.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui">
    <ui:composition template="/resources/template.xhtml">

        <ui:define name="login">
            <ui:include src="/resources/login.xhtml" />
        </ui:define>

        <ui:define name="centro">

            <p:outputPanel id="oplDialog" layout="block">
                <p:dialog id="dlgMsg" header="#{msg['modalPanel.msgAlerta']}"
                          position="center" minWidth="300" width="300" visible="true"
                          resizable="false" modal="true" rendered="#{autenticacaoController.exibeDialog}">
                    <h:panelGrid columns="1" cellspacing="5px">
                        <h:outputLabel id="oplMensagem" value="#{msg['mensagem.expirouSessao']}" styleClass="fonteAlerta" />
                        <p:commandButton  id="cbtOk" value="#{msg['botao.ok']}" immediate="true"
                                          ajax="false" action="#{autenticacaoController.fechaModal}" update="oplDialog, pgrLogin" />
                    </h:panelGrid>
                </p:dialog>
            </p:outputPanel>
        </ui:define>
    </ui:composition>
</html>

Quando ocorre uma exception e a sessão é expirada, a página é redirecionada para index.xhtml, o atributo exibeDialog do managedBean da página index recebe true, sendo exibido um dialog informando a questão. Neste dialog temos um botão OK, onde acionado, este fecha o dialog e seta pra variavel de sessão o valor false.

À pedidos foram adicionadas as demais classes externas utilizadas.

JSFUtil.java

package br.com.notaroberto.util;

//~--- JDK imports ------------------------------------------------------------
import java.lang.reflect.Method;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class JsfUtil {

    public static void addErrorMessageExcecao(Exception ex, String defaultMsg) {
        String msg = ex.getLocalizedMessage();

        if ((msg != null) && (msg.length() > 0)) {
            addErrorMessage(null, msg);
        } else {
            addErrorMessage(null, defaultMsg);
        }
    }

    public static void addErrorMessages(List<String> messages) {
        for (String message : messages) {
            addErrorMessage(null, message);
        }
    }

    public static void addErrorMessage(String idComponente, String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
        FacesContext.getCurrentInstance().addMessage(idComponente, facesMsg);
    }

    public static void addSuccessMessage(String idComponente, String msg) {
        FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg);
        FacesContext.getCurrentInstance().addMessage("idComponente", facesMsg);
    }

    public static String getRequestParameter(String key) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(key);
    }

    public static Object getObjectFromRequestParameter(String requestParameterName, Converter converter,
            UIComponent component) {
        String theId = JsfUtil.getRequestParameter(requestParameterName);
        return converter.getAsObject(FacesContext.getCurrentInstance(), component, theId);
    }

    public static Object getMethod(Object obj, String name) throws Exception {
        Method createMethod = obj.getClass().getMethod(name, new Class[0]);
        return createMethod.invoke(obj, new Object[0]);
    }

    public static void setAttribute(String valorObjeto, Object tipoObjeto) {
        FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put(valorObjeto, tipoObjeto);
    }

    public static Object getAttribute(String valorObjeto) {
        return FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get(valorObjeto);
    }
}

UsuarioDAO.java

package br.com.notaroberto.dao;

//~--- non-JDK imports --------------------------------------------------------
import br.com.notaroberto.model.Usuario;

//~--- JDK imports ------------------------------------------------------------
import br.com.notaroberto.util.CriptografaSenha;
import br.com.notaroberto.util.HibernateUtil;

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;

/**
 *
 * @author Lessandro
 */
public class UsuarioDAO {

    public void salva(Usuario usuario) {
        Session session = HibernateUtil.getSessao();
        HibernateUtil.inicializaTransacao();
        usuario.setDsSenha(CriptografaSenha.criptografar(usuario.getDsSenha()));
        session.save(usuario);
        HibernateUtil.aplicaTransacao();
        HibernateUtil.fechaSessao();

    }

    public void altera(Usuario usuario) {
        Session session = HibernateUtil.getSessao();
        HibernateUtil.inicializaTransacao();
        /* Senha informada nao esta criptografada, entao criptografa */
        if (usuario.getDsSenha().length() < 32) {
            usuario.setDsSenha(CriptografaSenha.criptografar(usuario.getDsSenha()));
        }
        session.update(usuario);
        HibernateUtil.aplicaTransacao();
        HibernateUtil.fechaSessao();
    }

    public void exclui(Usuario usuario) {
        Session session = HibernateUtil.getSessao();
        HibernateUtil.inicializaTransacao();
        session.delete(usuario);
        HibernateUtil.aplicaTransacao();
        HibernateUtil.fechaSessao();
    }

    public Usuario buscaPeloID(int id) {
        Usuario usuario = (Usuario) HibernateUtil.getSessao().get(Usuario.class, id);
        HibernateUtil.fechaSessao();
        return usuario;
    }

    @SuppressWarnings("unchecked")
    public List<Usuario> buscaTodos() {
        Criteria criteria = HibernateUtil.getSessao().createCriteria(Usuario.class);
        List<Usuario> usuarios = criteria.list();
        HibernateUtil.fechaSessao();
        return usuarios;
    }

    public Usuario buscaLoginSenha(String usuario, String senha) {
        Session session = HibernateUtil.getSessao();
        Criteria criteria = session.createCriteria(Usuario.class);
        HibernateUtil.inicializaTransacao();
        criteria.add(Expression.eq("dsLogin", usuario));
        criteria.add(Expression.eq("dsSenha", CriptografaSenha.criptografar(senha)));
        Usuario usuarioRecuperado = (Usuario) criteria.uniqueResult();
        HibernateUtil.fechaSessao();
        return usuarioRecuperado;
    }
}

Constantes.java

package br.com.notaroberto.util;

/**
 *
 * @author Lessandro
 */
public class Constantes {

    /* Opcoes Gerais */
    public static final String PAGINA_LOGIN = "/login.xhtml";
    public static final String PAGINA_INDEX = "/index.xhtml";
    public static final String PAGINA_EXIBIR_PERFIL = "exibirPerfis.xhtml";
    public static final String PAGINA_EXIBIR_USUARIO = "exibirUsuarios.xhtml";
    public static final Integer CLIENTE_TIPO_PESSOA_FISICA = 0;
    public static final Integer CLIENTE_TIPO_PESSOA_JURIDICA = 1;
    public static final Integer ID_PERFIL_ADMINISTRADOR = 1;

    public static final String MENU_CADASTRO = "Cadastro";
    public static final String MENU_HOME = "Home...";
    public static final String MENU_USUARIO = "Usuario...";
    public static final String MENU_PERFIL = "Perfil...";
    public static final String MENU_CLIENTE = "Cliente...";
    public static final String MENU_ESTOQUE = "Estoque...";
    public static final String MENU_FORMAPGTO = "Forma de Pagamento...";
    public static final String MENU_PEDIDO = "Pedido...";
    public static final String MENU_FORNECEDOR = "Fornecedor...";
    public static final String MENU_PRODUTO = "Produto...";
    public static final String MENU_ENCERRARSESSAO = "Encerrar Sessão...";
    public static final String MENU_SAIR = "Sair";

    public static final String URL_MENU_HOME = "/index?faces-redirect=true";
    public static final String URL_MENU_USUARIO = "/jsf/usuario/exibirUsuarios?faces-redirect=true";
    public static final String URL_MENU_PERFIL = "/jsf/perfil/exibirPerfis?faces-redirect=true";
    public static final String URL_MENU_CLIENTE = "/jsf/cliente/exibirClientes?faces-redirect=true";
    public static final String URL_MENU_ESTOQUE = "/jsf/estoque/exibirEstoques?faces-redirect=true";
    public static final String URL_MENU_FORMAPGTO = "/jsf/formaPgto/exibirFormasPgto?faces-redirect=true";
    public static final String URL_MENU_PEDIDO = "/jsf/pedido/exibirPedidos?faces-redirect=true";
    public static final String URL_MENU_FORNECEDOR = "/jsf/fornecedor/exibirFornecedores?faces-redirect=true";
    public static final String URL_MENU_PRODUTO = "/jsf/produto/exibirProdutos?faces-redirect=true";
    public static final String ACAO_MENU_ENCERRARSESSAO = "#{autenticacaoController.encerraSessao}";
}

Usuario.java


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.notaroberto.model;

//~--- JDK imports ------------------------------------------------------------
import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

/**
 *
 * @author Lessandro
 */
@Entity
@Table(name = "tb_usuario", catalog = "autopecas", schema = "", uniqueConstraints = {
    @UniqueConstraint(columnNames = {"NM_USUARIO"})})
public class Usuario implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID_USUARIO", nullable = false)
    private Integer idUsuario;
    @Column(name = "DS_BAIRRO", nullable = false, length = 50)
    private String dsBairro;
    @Column(name = "DS_CIDADE", nullable = false, length = 50)
    private String dsCidade;
    @Column(name = "DS_ESTADO", nullable = false, length = 2)
    private String dsEstado;
    @Column(name = "DS_LOGIN", nullable = false, length = 20)
    private String dsLogin;
    @Column(name = "DS_RUA", nullable = false, length = 100)
    private String dsRua;
    @Column(name = "DS_SENHA", nullable = false, length = 32)
    private String dsSenha;
    @Column(name = "NM_USUARIO", nullable = false, length = 100)
    private String nmUsuario;
    @Column(name = "NU_CEP")
    private Integer nuCep;
    @Column(name = "NU_CPF", nullable = false, length = 11)
    private String nuCpf;
    @Column(name = "NU_TEL_FIXO", columnDefinition="bigint", nullable = false)
    private BigInteger nuTelFixo;
    @Column(name = "NU_TEL_CONTATO", columnDefinition="bigint", nullable = false)
    private BigInteger nuTelContato;
    @Column(name = "NU_LOCAL", nullable = false)
    private int nuLocal;
    @JoinColumn(name = "ID_PERFIL", referencedColumnName = "ID_PERFIL", nullable = false)
    @ManyToOne(optional = false)
    private Perfil perfil;

    public Usuario() {
    }

    public Usuario(Integer idUsuario) {
        this.idUsuario = idUsuario;
    }

    public Integer getIdUsuario() {
        return idUsuario;
    }

    public void setIdUsuario(Integer idUsuario) {
        this.idUsuario = idUsuario;
    }

    public String getNmUsuario() {
        return nmUsuario;
    }

    public void setNmUsuario(String nmUsuario) {
        this.nmUsuario = nmUsuario;
    }

    public String getDsRua() {
        return dsRua;
    }

    public void setDsRua(String dsRua) {
        this.dsRua = dsRua;
    }

    public int getNuLocal() {
        return nuLocal;
    }

    public void setNuLocal(int nuLocal) {
        this.nuLocal = nuLocal;
    }

    public String getDsBairro() {
        return dsBairro;
    }

    public void setDsBairro(String dsBairro) {
        this.dsBairro = dsBairro;
    }

    public Integer getNuCep() {
        return nuCep;
    }

    public void setNuCep(Integer nuCep) {
        this.nuCep = nuCep;
    }

    public String getDsCidade() {
        return dsCidade;
    }

    public void setDsCidade(String dsCidade) {
        this.dsCidade = dsCidade;
    }

    public String getDsEstado() {
        return dsEstado;
    }

    public void setDsEstado(String dsEstado) {
        this.dsEstado = dsEstado;
    }

    public String getDsLogin() {
        return dsLogin;
    }

    public void setDsLogin(String dsLogin) {
        this.dsLogin = dsLogin;
    }

    public String getDsSenha() {
        return dsSenha;
    }

    public void setDsSenha(String dsSenha) {
        this.dsSenha = dsSenha;
    }

    public Perfil getPerfil() {
        return perfil;
    }

    public void setPerfil(Perfil perfil) {
        this.perfil = perfil;
    }

    public String getNuCpf() {
        return nuCpf;
    }

    public void setNuCpf(String nuCpf) {
        this.nuCpf = nuCpf;
    }

    public BigInteger getNuTelFixo() {
        return nuTelFixo;
    }

    public void setNuTelFixo(BigInteger nuTelFixo) {
        this.nuTelFixo = nuTelFixo;
    }

    public BigInteger getNuTelContato() {
        return nuTelContato;
    }

    public void setNuTelContato(BigInteger nuTelContato) {
        this.nuTelContato = nuTelContato;
    }

    @Override
    public int hashCode() {
        int hash = 0;

        hash += ((idUsuario != null)
                ? idUsuario.hashCode()
                : 0);

        return hash;
    }

    @Override
    public boolean equals(Object object) {

        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Usuario)) {
            return false;
        }

        Usuario other = (Usuario) object;

        if (((this.idUsuario == null) && (other.idUsuario != null))
                || ((this.idUsuario != null) && !this.idUsuario.equals(other.idUsuario))) {
            return false;
        }

        return true;
    }

    @Override
    public String toString() {
        return "br.com.notaroberto.model.Usuario[idUsuario=" + idUsuario + "]";
    }
}

CriptografaSenha.java

package br.com.notaroberto.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CriptografaSenha {

    private static MessageDigest md = null;

    /**
     * Metodo estatico para a geracao do algoritmo de criptografia.
     */
    static {
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Criptografa a senha.
     *
     * @param senha
     *            String A senha normal.
     * @return String A senha criptografada.
     */
    public static String criptografar(String senha) {
        if (md != null) {
            return new String(hexCodes(md.digest(senha.getBytes())));
        }
        return null;
    }

    private static char[] hexCodes(byte[] text) {
        char[] hexOutput = new char[text.length * 2];
        String hexString;

        for (int i = 0; i < text.length; i++) {
            hexString = "00" + Integer.toHexString(text[i]);
            hexString.toUpperCase().getChars(hexString.length() - 2,
                    hexString.length(), hexOutput, i * 2);
        }
        return hexOutput;
    }
}

HibernateUtil.java

package br.com.notaroberto.util;

import br.com.notaroberto.model.Cliente;
import br.com.notaroberto.model.Estoque;
import br.com.notaroberto.model.FormaPgto;
import br.com.notaroberto.model.Fornecedor;
import br.com.notaroberto.model.Pedido;
import br.com.notaroberto.model.PedidoProduto;
import br.com.notaroberto.model.Perfil;
import br.com.notaroberto.model.Produto;
import br.com.notaroberto.model.Usuario;
import com.mysql.jdbc.Connection;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.Hibernate;

public class HibernateUtil {

    private static SessionFactory sessionFactory;
    private static AnnotationConfiguration configuracao;
    private static ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
    private static Logger log = Logger.getLogger(HibernateUtil.class);

    public static void inicializa() {
        try {
            sessionFactory = getConfiguracao().buildSessionFactory();
            log.info("Hibernate Inicializado.");
        } catch (Throwable e) {
            log.error("Falha na inicialização do Hibernate: " + e);
        }
    }

    public static AnnotationConfiguration getConfiguracao() {
        if (configuracao == null) {
            configuracao = new AnnotationConfiguration();
            /* Classes devem ser informadas aqui para anotacao */
            configuracao.addAnnotatedClass(Perfil.class);
            configuracao.addAnnotatedClass(Usuario.class);
            configuracao.addAnnotatedClass(Cliente.class);
            configuracao.addAnnotatedClass(Estoque.class);
            configuracao.addAnnotatedClass(Fornecedor.class);
            configuracao.addAnnotatedClass(FormaPgto.class);
            configuracao.addAnnotatedClass(Produto.class);
            configuracao.addAnnotatedClass(Pedido.class);
            configuracao.addAnnotatedClass(PedidoProduto.class);
        }
        return configuracao;
    }

    public static void setConfiguration(AnnotationConfiguration cfg) {
        HibernateUtil.configuracao = cfg;
    }

    public static void reinicializa() {
        fechaSessao();
        inicializa();
        getSessao();
    }

    /**
     * Inicializa as propriedades de um objeto persistido.
     */
    public static void initializeProperties(Object obj) {
        try {
            if (!Hibernate.isInitialized(obj)) {
                Hibernate.initialize(obj);
            }
        } catch (Exception e) {
            log.error("Falha ao inicializar as propriedades do objeto: " + e);
        }
    }

    /**
     * Atualiza um objeto persistido.
     */
    public static void atualizaObjeto(Object obj) {
        try {
            Session s = HibernateUtil.getSessao();
            s.refresh(obj);
        } catch (Exception e) {
            log.error("Falha ao atualizar o objeto: " + e);
        }
    }

    /**
     * Limpa a session corrente.
     */
    public static void limpaSessao() {
        try {
            Session s = HibernateUtil.getSessao();
            s.clear();
        } catch (Exception e) {
            log.error("Falha ao limpar a sessão: " + e);
        }
    }

    /**
     * Inicializa transacao.
     */
    public static Connection recuperaConexao() {
        Connection con = null;
        try {
            con = (Connection) HibernateUtil.getConfiguracao().buildSettings().getConnectionProvider().getConnection();
        } catch (Throwable e) {
            log.error("Falha ao recuperar a conexão: " + e);
        }
        return con;
    }



    /**
     * Inicializa transacao.
     */
    public static void inicializaTransacao() {
        try {
            Session s = HibernateUtil.getSessao();
            s.beginTransaction();
        } catch (Throwable e) {
            log.error("Falha ao inicializar a transação: " + e);
        }
    }

    /**
     * Aplica transacao.
     */
    public static void aplicaTransacao() {
        try {
            Session s = HibernateUtil.getSessao();
            s.getTransaction().commit();
        } catch (Exception e) {
            log.error("Falha ao aplicar a transação: " + e);
        }
    }

    /**
     * Retorna uma Session existente, ou então abre uma nova e associa a ThreadLocal.
     * @return uma sessão do Hibernate
     */
    public static Session getSessao() {
        Session s = null;
        try {
            if (sessionFactory == null) {
                inicializa();
                fechaSessao();
            }

            s = (Session) threadSession.get();

            if (s == null) {
                s = sessionFactory.openSession();
                threadSession.set(s);
            }
        } catch (Exception e) {
            log.error("Falha ao recuperar a sessão: " + e);
        }
        return s;
    }

    /**
     * Fecha a Session associada a ThreadLocal.
     */
    public static void fechaSessao() {
        try {
            Session s = (Session) threadSession.get();
            threadSession.set(null);
            if (s != null && s.isOpen()) {
                s.close();
            }
        } catch (Exception e) {
            log.error("Falha ao fechar a sessão: " + e);
        }
    }
}

Para versões posteriores ao Primefaces 2.2, segue alguns links que abordam o assunto:


http://weblogs.java.net/blog/edburns/archive/2009/09/03/dealing-gracefully-viewexpiredexception-jsf2
http://www.gregbugaj.com/?p=164
http://javalabor.blogspot.com.br/2011/09/jsf-2-global-exception-handling.html
Adding global exception handling using JSF 2.x ExceptionHandler

Espero que tenha ajudado,
Grande abraço a todos,
Até a próxima 🙂

agosto 4, 2010

agosto 2, 2010

Mensagem de "Um ou mais recursos possuem o destino de ‘head’, mas nenhum componente de ‘head’ foi definido na exibição." no JSF 2.0

Filed under: Desenvolvimento Web — Tags:, , , — semprejava @ 3:47 pm

Olá amigos, bom dia.
Para quem está obtendo essa mensagem “Um ou mais recursos possuem o destino de ‘head’, mas nenhum componente de ‘head’ foi definido na exibição.” no JSF 2.0 deve atentar-se por informar a tag da forma exibida abaixo:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>  <=
            <title>Sistema XXX</title>
    </h:head>
    <h:body>
		<f:view>
			<h:form id="form" prependId="false">
				<h:outputLabel value="xxxx" />
			</h:form>
		</f:view>
	</h:body>
</h:form>            

Se esta tag for informada como “<head>” apenas, esta não é interpretada.
Abs,
Lessandro

agosto 1, 2010

Desenvolvimento de Aplicações WEB para diversos segmentos

Filed under: Desenvolvimento Web — Tags:, , , , — semprejava @ 9:29 pm

Olá pessoal, boa tarde.
Aproveitando para divulgar que desenvolvo aplicações Web para diversos segmentos. Protótipo disponível em: http://lessandronp.homeip.net:8080/AutoPecas
Sistema totalmente desenvolvido utilizando o framework JavaServer Faces + Primefaces 2.1 + Hibernate + EJB + MySQL.
Abraços,
Att,
Lessandro

Older Posts »

Blog no WordPress.com.

Crie um site como este com o WordPress.com
Comece agora