<http://schema.org/articleBody>
"Neste post vou falar sobre um assunto um pouco trivial e que qualquer iniciante no framework &lt;strong&gt;JSF&lt;/strong&gt; pode se perder: &lt;strong&gt;As fases do JSF e onde interceptar a navega\u00E7\u00E3o para que o usu\u00E1rio realize a autentica\u00E7\u00E3o&lt;/strong&gt;.\n\n\u00C9 importante que voc\u00EA saiba o que \u00E9 JSF e como configur\u00E1-lo em seu editor, aqui estarei utilizando o Eclipse, caso n\u00E3o saiba como configurar em seu editor, ao final, deixarei alguns links para lhe ajudar.\n\nVamos la =) .\n\n&lt;h2&gt;Fases do JSF&lt;/h2&gt;\n\nO JSF funciona atrav\u00E9s de fases que s\u00E3o invocadas a partir do momento que abrimos uma p\u00E1gina.\n\nEnt\u00E3o, o JSF executa um processo para coletar as informa\u00E7\u00F5es, validar e criar a p\u00E1gina de resposta que ser\u00E1 enviada ao usu\u00E1rio.\n\nEste processo \u00E9 composto por 6 fases:\n\n&lt;img class=\"alignnone size-full wp-image-55231\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/fases-jsf.png\" alt=\"Fases do JSF\" width=\"748\" height=\"411\" /&gt;\n\n&amp;nbsp;\n\n&lt;h3&gt;Restore View&lt;/h3&gt;\n\nFase onde o JSF criar\u00E1 uma \u00E1rvore de componentes, contendo um objeto para cada componente visual do formul\u00E1rio e, se for a primeira exibi\u00E7\u00E3o da p\u00E1gina, ele pula todas as fases e vai para a &lt;strong&gt;Render Response&lt;/strong&gt;.\n\nSe a p\u00E1gina j\u00E1 foi exibida, o framework buscar\u00E1 pela \u00E1rvore j\u00E1 existente.\n\n&lt;h3&gt;Apply Request Values&lt;/h3&gt;\n\nNesta fase, o framework pega os valores do formul\u00E1rio, eles s\u00E3o recebidos como Strings independente do tipo.\n\n&lt;h3&gt;Process Validation&lt;/h3&gt;\n\nO JSF converte os valores existentes para os tipos que est\u00E3o vinculados nas propriedades dos Managed Beans.\n\nAp\u00F3s a convers\u00E3o, \u00E9 feita a valida\u00E7\u00E3o desses valores.\n\nSe ocorrer algum erro em qualquer dessas etapas, o JSF redireciona para a fase Render Response.\n\n&lt;h3&gt;Update Model Values&lt;/h3&gt;\n\nOs dados convertidos s\u00E3o colocados nos objetos Managed Beans que est\u00E3o vinculados.\n\n&lt;h3&gt;Invoke Application&lt;/h3&gt;\n\nO m\u00E9todo do atributo action que est\u00E1 vinculado a algum bot\u00E3o que foi acionado \u00E9 avalido pela Expression Language e seu valor \u00E9 retornado.\n\n&lt;h3&gt;Render Response&lt;/h3&gt;\n\nO JSF processa a p\u00E1gina recebida pelas fases anteriores e gera o c\u00F3digo XHTML para o usu\u00E1rio.\n\n&lt;h2&gt;Cria\u00E7\u00E3o do Login&lt;/h2&gt;\n\nPrimeiramente vamos criar nosso xhtml com os campos e bot\u00F5es para login vinculado com um Managed Bean e outro xhtml para ser a p\u00E1gina inicial ap\u00F3s o login do usu\u00E1rio.\n\nA p\u00E1gina deve ter os campos vinculados a um Managed Bean chamado usu\u00E1rio e um bot\u00E3o vinculado a algum m\u00E9todo para logar.\n\nEste foi meu c\u00F3digo, claro, h\u00E1 diversos meios diferente para se fazer o mesmo:\n\n&lt;pre class=\"lang-html\"&gt;&amp;lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?&amp;gt;\n&amp;lt;!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"&amp;gt;\n&amp;lt;html xmlns=\"http://www.w3.org/1999/xhtml\"\n      xmlns:h=\"http://java.sun.com/jsf/html\"\n      xmlns:f=\"http://java.sun.com/jsf/core\"\n&gt;\n&amp;lt;h:head&amp;gt;\n&amp;lt;meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" /&amp;gt;\n&amp;lt;title&amp;gt;Login&amp;lt;/title&amp;gt;\n&amp;lt;/h:head&amp;gt;\n&amp;lt;h:body&amp;gt;\n    &amp;lt;h:form&amp;gt;\n        &amp;lt;h:panelGrid columns=\"2\"&amp;gt; \n            &amp;lt;h:outputLabel value=\"Usu\u00E1rio:\" /&amp;gt;\n            &amp;lt;h:inputText value=\"#{usuario.usuario}\" size=\"20\" /&amp;gt;\n            \n            &amp;lt;h:outputLabel value=\"Senha:\" /&amp;gt;\n            &amp;lt;h:inputSecret value=\"#{usuario.senha}\" size=\"20\" /&amp;gt;\n                \n            &amp;lt;h:commandButton value=\"Logar\" action=\"#{usuario.logar}\" /&amp;gt;\n        &amp;lt;/h:panelGrid&amp;gt;\n        &amp;lt;h:messages /&amp;gt;    \n    &amp;lt;/h:form&amp;gt;\n&amp;lt;/h:body&amp;gt;\n&amp;lt;/html&amp;gt;\n&lt;/pre&gt;\n\nE este foi o resultado:\n\n&lt;img class=\"alignnone size-full wp-image-55232\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/result-jsf-login.png\" alt=\"Formul\u00E1rio de login XHTMl\" width=\"261\" height=\"89\" /&gt;\n\nNo m\u00E9todo logar vou verificar se o usu\u00E1rio e a senha correspondem ao meu nome: \"Julio\".\n\nCaso o usu\u00E1rio ou a senha forem diferentes de \"Julio\", exibirei uma mensagem informando que o usu\u00E1rio \u00E9 inv\u00E1lido.\n\nEm outros casos ser\u00E1 invocado um &lt;em&gt;DAO&lt;/em&gt;, que verificar\u00E1 se o usu\u00E1rio existe na base de dados ou o que for preciso.\n\nCrie, tamb\u00E9m, uma p\u00E1gina de resposta caso o usu\u00E1rio esteja correto.\n\nSegue o c\u00F3digo da classe Usu\u00E1rio:\n\n&lt;pre class=\"lang-java\"&gt;package root;\n\nimport javax.faces.application.FacesMessage;\nimport javax.faces.bean.ManagedBean;\nimport javax.faces.bean.SessionScoped;\nimport javax.faces.context.FacesContext;\n\n@ManagedBean\n@SessionScoped\npublic class Usuario {\n    private String usuario = \"\";\n    private String senha = \"\";\n    \n    public String logar(){\n        if(usuario.equals(\"Julio\") &amp;amp;&amp;amp; senha.equals(\"Julio\")){\n            return \"pag-sucesso\";\n        }\n        FacesContext ctx = FacesContext.getCurrentInstance();\n        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, \"Usu\u00E1rio inv\u00E1lido\", \"Usu\u00E1rio inv\u00E1lido\");\n        ctx.addMessage(null, msg);\n        return \"\";              \n    }\n    \n    \n    public String getUsuario() {\n        return usuario;\n    }\n    public void setUsuario(String usuario) {\n        this.usuario = usuario;\n    }\n    public String getSenha() {\n        return senha;\n    }\n    public void setSenha(String senha) {\n        this.senha = senha;\n    }\n}\n&lt;/pre&gt;\n\nE, tamb\u00E9m, o c\u00F3digo do XHTML de resposta em caso de sucesso.\n\n&lt;pre class=\"lang-html\"&gt;&amp;lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?&amp;gt;\n&amp;lt;!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\"&amp;gt;\n&amp;lt;html xmlns=\"http://www.w3.org/1999/xhtml\"\n      xmlns:h=\"http://java.sun.com/jsf/html\"\n      xmlns:f=\"http://java.sun.com/jsf/core\"\n&gt;\n&amp;lt;h:head&amp;gt;\n&amp;lt;meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\" /&amp;gt;\n&amp;lt;title&amp;gt;Sucesso!!&amp;lt;/title&amp;gt;\n&amp;lt;/h:head&amp;gt;\n&amp;lt;h:body&amp;gt;\n    Usu\u00E1rio logado!!!\n&amp;lt;/h:body&amp;gt;\n&amp;lt;/html&amp;gt;\n&lt;/pre&gt;\n\n&lt;h3&gt;&lt;/h3&gt;\n\n&lt;h3&gt;Testes&lt;/h3&gt;\n\nVamos testar nossa p\u00E1gina:\n\n&lt;img class=\"alignnone size-full wp-image-55233\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/teste-jsf.png\" alt=\"Teste do login em sucesso\" width=\"295\" height=\"111\" /&gt;\nPrimeiramente coloquei os campos de modo correto, ou seja, com os valores em \"Julio\", e ap\u00F3s pressionar o bot\u00E3o \"Logar\" a p\u00E1gina de sucesso foi retornada como esperado.\n\n&lt;img class=\"alignnone size-full wp-image-55234\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/teste-jsf-sucesso.png\" alt=\"teste-jsf-sucesso\" width=\"159\" height=\"62\" /&gt;\nMas tem um problema, conseguimos acessarmos diretamente a p\u00E1gina de sucesso, pois n\u00E3o h\u00E1 nenhuma valida\u00E7\u00E3o se o usu\u00E1rio est\u00E1 logado. Em casos de sistemas grandes, isso pode ser um enorme problema, pois qualquer usu\u00E1rio poderia ter acesso a informa\u00E7\u00F5es n\u00E3o permitidas.\n\n&lt;h3&gt;Corre\u00E7\u00E3o&lt;/h3&gt;\n\nDevemos criar um login que valide se o usu\u00E1rio j\u00E1 est\u00E1 no sistema, ent\u00E3o vamos criar uma classe que sirva como ouvinte entre as fases do JSF.\n\nPara isto, \u00E9 preciso:\n\n&lt;ul&gt;\n&lt;li&gt;Criar uma classe que implemente a interface &lt;strong&gt;PhaseListener&lt;/strong&gt;;&lt;/li&gt;\n&lt;li&gt;Registrar no faces-config.xml.&lt;/li&gt;\n&lt;/ul&gt;\n\nCriarei uma classe chamada \"Listener\" que implementa a interface PhaseListener.\n\nEsta interface possui 3 m\u00E9todos:\n\n&lt;ul&gt;\n&lt;li&gt;beforePhase: c\u00F3digo que ser\u00E1 executado antes do processamento da fase;&lt;/li&gt;\n&lt;li&gt;afterPhase: c\u00F3digo que ser\u00E1 executado ap\u00F3s o processamento da fase;&lt;/li&gt;\n&lt;li&gt;getPhaseId: retorna um Enum com o nome da fase atual.&lt;/li&gt;\n&lt;/ul&gt;\n\nDevemos implementar nosso m\u00E9todo para verificar se o usu\u00E1rio est\u00E1 logado no m\u00E9todo \"afterPhase\".\n\nPara verificar se a p\u00E1gina que est\u00E1 sendo acessada \u00E9 diferente da p\u00E1gina \"login.xhtml\" devemos pegar a inst\u00E2ncia atual do \"FacesContext\" e, partir dele, pegar o ViewRoot e o ViewId que cont\u00E9m o nome da p\u00E1gina atual:\n\n&lt;pre class=\"lang-java\"&gt;package root;\n\nimport javax.faces.application.Application;\nimport javax.faces.application.NavigationHandler;\nimport javax.faces.context.FacesContext;\nimport javax.faces.event.PhaseEvent;\nimport javax.faces.event.PhaseId;\nimport javax.faces.event.PhaseListener;\n\npublic class Listener implements PhaseListener{\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    public void beforePhase(PhaseEvent arg0) {\n    }\n\n    @Override\n    public void afterPhase(PhaseEvent arg0) {\n        FacesContext ctx = FacesContext.getCurrentInstance();\n        if(!ctx.getViewRoot().getViewId().equals(\"/login.xhtml\")){\n                    \n        }\n    }\n\n    @Override\n    public PhaseId getPhaseId() {\n        return null;\n    }\n\n}\n\n&lt;/pre&gt;\n\nAp\u00F3s isto, \u00E9 preciso verificar se o usu\u00E1rio est\u00E1 logado, isto pode ser feito com um atributo booleano na classe Usuario ou verificar se os par\u00E2metros est\u00E3o de acordo com o que queremos, vou utilizar esta segunda op\u00E7\u00E3o.\n\nPara pegar o objeto Usuario que queremos, devemos utilizar o objeto \"Application\" a partir do FacesContext atual, atrav\u00E9s do m\u00E9todo \"getApplication\".\n\nEnt\u00E3o utilizamos o m\u00E9todo \"evaluateExpressionGet\" do objeto \"Application\":\n\n&lt;pre class=\"lang-java\"&gt;package root;\n\nimport javax.faces.application.Application;\nimport javax.faces.application.NavigationHandler;\nimport javax.faces.context.FacesContext;\nimport javax.faces.event.PhaseEvent;\nimport javax.faces.event.PhaseId;\nimport javax.faces.event.PhaseListener;\n\npublic class Listener implements PhaseListener{\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    public void beforePhase(PhaseEvent arg0) {\n    }\n\n    @Override\n    public void afterPhase(PhaseEvent arg0) {\n        FacesContext ctx = FacesContext.getCurrentInstance();\n        if(!ctx.getViewRoot().getViewId().equals(\"/login.xhtml\")){\n            Application app = ctx.getApplication();\n            Usuario u = app.evaluateExpressionGet(ctx, \"#{usuario}\", Usuario.class);\n        }\n    }\n\n    @Override\n    public PhaseId getPhaseId() {\n        return null;\n    }\n\n}\n&lt;/pre&gt;\n\nAgora aplicamos nossa valida\u00E7\u00E3o, no meu caso apenas peguei o atributo usuario a partir do objeto Usuario atual e verifiquei se \u00E9 diferente de \"Julio\", se for, &lt;strong&gt;retorno a navega\u00E7\u00E3o para a p\u00E1gina login&lt;/strong&gt;.\n\nIsto \u00E9 feito a partir do objeto \"NavigationHandler\" conseguido a atrav\u00E9s do objeto \"Application\" e invoco o m\u00E9todo \"handleNavigation\", que altera o fluxo. Por \u00FAltimo chamo o m\u00E9todo \"renderResponse\" do FacesContext.\n\nE, claro, devemos indicar ao Listener qual fase que desejamos interceptar, que no nosso caso \u00E9 a \"Restore View\" indicando no m\u00E9todo \"getPhaseId\".\n\n&lt;pre class=\"&amp;quot;lang-java\"&gt;package root;\n\nimport javax.faces.application.Application;\nimport javax.faces.application.NavigationHandler;\nimport javax.faces.context.FacesContext;\nimport javax.faces.event.PhaseEvent;\nimport javax.faces.event.PhaseId;\nimport javax.faces.event.PhaseListener;\n\npublic class Listener implements PhaseListener{\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    public void beforePhase(PhaseEvent arg0) {\n    }\n\n    @Override\n    public void afterPhase(PhaseEvent arg0) {\n        FacesContext ctx = FacesContext.getCurrentInstance();\n        if(!ctx.getViewRoot().getViewId().equals(\"/login.xhtml\")){\n            Application app = ctx.getApplication();\n            Usuario u = app.evaluateExpressionGet(ctx, \"#{usuario}\", Usuario.class);\n            if(!u.getUsuario().equals(\"Julio\")){\n                NavigationHandler handler = app.getNavigationHandler();\n                handler.handleNavigation(ctx, \"\", \"login\");\n                ctx.renderResponse();\n            }\n        }\n    }\n\n    @Override\n    public PhaseId getPhaseId() {\n        return PhaseId.RESTORE_VIEW;\n    }\n}&lt;/pre&gt;\n\nPara que funcione, precisamos registrar no faces-config.xml que ele \u00E9 um Listener.\n\n&lt;pre class=\"lang-xml\"&gt;&amp;lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&amp;gt;\n&amp;lt;faces-config\n    xmlns=\"http://xmlns.jcp.org/xml/ns/javaee\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd\"\n    version=\"2.2\"&amp;gt;\n    &amp;lt;lifecycle&amp;gt;\n        &amp;lt;phase-listener&amp;gt;root.Listener&amp;lt;/phase-listener&amp;gt;\n    &amp;lt;/lifecycle&amp;gt;\n\n&amp;lt;/faces-config&amp;gt;\n&lt;/pre&gt;\n\nAgora ao tentarmos entrar na p\u00E1gina de sucesso diretamente, ele n\u00E3o vai.\n&lt;img class=\"alignnone size-full wp-image-55235\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/resultado-final-jsf.png\" alt=\"Resultado final\" width=\"479\" height=\"267\" /&gt;\n\nPara quem deseja obter a URL correta, apenas adicionar \"?faces-redirect=true\" ao final da String de redirecionamento no Listener:\n\n&lt;pre class=\"lang-java\"&gt;package root;\n\nimport javax.faces.application.Application;\nimport javax.faces.application.NavigationHandler;\nimport javax.faces.context.FacesContext;\nimport javax.faces.event.PhaseEvent;\nimport javax.faces.event.PhaseId;\nimport javax.faces.event.PhaseListener;\n\npublic class Listener implements PhaseListener{\n\n    /**\n     * \n     */\n    private static final long serialVersionUID = 1L;\n\n    @Override\n    public void beforePhase(PhaseEvent arg0) {\n    }\n\n    @Override\n    public void afterPhase(PhaseEvent arg0) {\n        FacesContext ctx = FacesContext.getCurrentInstance();\n        if(!ctx.getViewRoot().getViewId().equals(\"/login.xhtml\")){\n            Application app = ctx.getApplication();\n            Usuario u = app.evaluateExpressionGet(ctx, \"#{usuario}\", Usuario.class);\n            if(!u.getUsuario().equals(\"Julio\")){\n                NavigationHandler handler = app.getNavigationHandler();\n                handler.handleNavigation(ctx, \"\", \"login?faces-redirect=true\");\n                ctx.renderResponse();\n            }\n        }\n    }\n\n    @Override\n    public PhaseId getPhaseId() {\n        return PhaseId.RESTORE_VIEW;\n    }\n\n}\n&lt;/pre&gt;\n\nEnt\u00E3o:\n\n&lt;img class=\"alignnone size-full wp-image-55236\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/alteracao-param-jsf-2.png\" alt=\"Entrada no browser\" width=\"439\" height=\"92\" /&gt;\n\nRetorna:\n\n&lt;img class=\"alignnone size-full wp-image-55237\" src=\"http://tableless.com.br/wp-content/uploads/2016/07/alteracao-param-jsf-3.png\" alt=\"Resposta no browser\" width=\"383\" height=\"193\" /&gt;\n\nObtendo o resultado desejado.\n\nComente em caso de d\u00FAvidas ou falhas =D.\n\nEm meu blog tem alguns outros artigos deste mesmo tipo, se deseja ver:\u00A0&lt;a href=\"http://jcdourado.github.io\"&gt;http://jcdourado.github.io&lt;/a&gt;\n\nObrigado!!\n\nSegue alguns links de artigos e alguns livros que ajudam nessa caminhada:\n\n&lt;a href=\"http://www.devmedia.com.br/jsf-session-criando-um-modulo-de-login/30975\"&gt;http://www.devmedia.com.br/jsf-session-criando-um-modulo-de-login/30975&lt;/a&gt;\n\n&lt;a href=\"http://www.devmedia.com.br/java-web-criando-uma-tela-de-login-com-jpa-jsf-primefaces-e-mysql/32456\"&gt;http://www.devmedia.com.br/java-web-criando-uma-tela-de-login-com-jpa-jsf-primefaces-e-mysql/32456&lt;/a&gt;\n\n&lt;a href=\"http://www.universidadejava.com.br/materiais/jsf-tela-login/\"&gt;http://www.universidadejava.com.br/materiais/jsf-tela-login/&lt;/a&gt;\n\nLivro: &lt;strong&gt;JSF Eficaz&lt;/strong&gt; - Casa do C\u00F3digo.\n\n&amp;nbsp;"^^<http://www.w3.org/2001/XMLSchema#string>
<http://tableless.com.br/construindo-uma-pagina-com-login-no-jsf/>