Guia Essencial de JSF: Escopos, Mensagens, I18N e Mais

Classificado em Computação

Escrito em em português com um tamanho de 12,01 KB

1. Escopos JSF: Requisição, Sessão e Aplicação

Descreva os escopos de Requisição, Sessão e Aplicação do JSF.

  • @RequestScoped: Existe uma instância pelo tempo de duração da requisição feita pelo usuário.
  • @SessionScoped: Existe uma instância para cada usuário.
  • @ApplicationScoped: Apenas uma instância da classe em toda a aplicação. Todos os usuários acessam a mesma instância.

2. Tipos de Mensagens no JSF

Quais os dois tipos de mensagens do JSF? Escreva um trecho código para criar cada um dos tipos.

Mensagens Globais:

Não estão relacionadas a nenhum componente.

FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN,
"Dia inválido!", "O dia tem que ser > 0 e <>");
FacesContext.getCurrentInstance().addMessage(null, message);

Mensagens relacionadas a um componente específico:

FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
"Dia inválido!", "O dia tem que ser > 0 e <>");
FacesContext.getCurrentInstance().addMessage("frm:nome", message);

3. Exemplo JSF: Somar Dois Números

Escreva uma aplicação JSF que soma dois números e exibe o resultado.

Classe Java Bean: Calcular.java

@ManagedBean
public class Calcular {

    private int num1, num2;

    public void somaDoisNumeros() {
        int resultado;
        resultado = num1 + num2;
        System.out.println(resultado);
    }

    public int getNum1() {
        return num1;
    }

    public void setNum1(int num1) {
        this.num1 = num1;
    }

    public int getNum2() {
        return num2;
    }

    public void setNum2(int num2) {
        this.num2 = num2;
    }
}

Página XHTML: index.xhtml

<h:form id="soma-dois-numeros">
    <h:outputLabel value="Numero 1:" />
    <h:inputText value="#{calcular.num1}" /><br/>

    <h:outputLabel value="Numero 2:" />
    <h:inputText value="#{calcular.num2}" /><br/>

    <h:commandButton value="Calcular" action="#{calcular.somaDoisNumeros}" />
</h:form>

4. Internacionalização (I18N) no JSF

Sobre internacionalização, descreva as duas formas de carregar um arquivo de mensagens de uma aplicação e explique qual é a mais eficiente.

As duas formas de carregar o arquivo de mensagens são: faces-config.xml e a tag Core.

Das duas formas apresentadas, a do arquivo faces-config.xml é a mais eficiente, pois é utilizado em todo o aplicativo e não somente na página configurada.

5. Imprimindo Mensagens I18N no JSF

Descreva o processo para imprimir o texto “Olá Mundo” em Português e Inglês, de acordo com o idioma do usuário.

  • No JSF, funciona através de arquivos de propriedades (.properties) com as mensagens do sistema, chamado de message bundle.
  • Os arquivos são criados de acordo com os Locales desejados. Um Locale é definido por um idioma (pt ou en) e por um país (BR ou US), que é opcional.
  • Para que o mecanismo de mensagens funcione, precisamos informar à aplicação qual message bundle carregar e onde encontrá-lo.
  • Devemos criar um arquivo .properties em um pacote da nossa aplicação (ex.: com.exemplo.recursos).
  • Cada linha deste arquivo possui pares de chaves e descrições, onde as chaves são usadas apenas como referência para quando precisarmos resgatar as descrições.
  • Exemplo (message.properties):
search=Search
code=Code
name=Name
city=City

6. Recuperando Locales no JSF

Escreva um código para recuperar o Locale do Browser, e todos os Locales suportados na aplicação.

  • Recuperar o Locale do Browser:
FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
  • Recuperar os Locales suportados:
FacesContext.getCurrentInstance().getApplication().getSupportedLocales();

7. Formatando Datas no JSF

Escreva um trecho de código JSF para imprimir a seguinte data formatada: 23 de Novembro de 2014.

Classe Java Bean: ExemploData.java

@ManagedBean
@SessionScoped
public class ExemploData {

    private Date data;

    public Date getData() {
        return data;
    }

    public void setData(Date data) {
        this.data = data;
    }
}

Página XHTML: index.xhtml

<h:form id="form-data">
    <h:panelGrid columns="3">
        <h:outputLabel value="Recebe Data:" />
        <h:inputText id="date" value="#{exemploData.data}"
                     size="20" required="true"
                     label="Receipt Date" >
            <f:convertDateTime pattern="d-M-yyyy" />
        </h:inputText>
        <h:message for="date" style="color:red" />
    </h:panelGrid>
    <h:commandButton value="Mostrar" action="exibeData.xhtml" />
</h:form>

Página XHTML: exibeData.xhtml

<h:body>
    <h:form>
        <h:panelGrid columns="2">
            <h:outputLabel value="Recebe Data:" />
            <h:outputText value="#{exemploData.data}" >
                <f:convertDateTime type="long" />
            </h:outputText>
        </h:panelGrid>
    </h:form>
</h:body>

8. Criando um Conversor Customizado no JSF

Descreva um passo a passo necessário para criar o seu próprio Conversor.

O primeiro passo é criar uma classe que implementa a interface javax.faces.convert.Converter.

Exige a implementação de dois métodos:

  • Object getAsObject(FacesContext context, UIComponent component, String value): deve transformar uma String em um objeto Java. Se a string recebida for inválida, podemos criar uma mensagem de erro e lançar uma exceção do tipo javax.faces.convert.ConverterException com tal mensagem.
  • String getAsString(FacesContext context, UIComponent component, Object value): deve converter um objeto Java em uma String.

9. Registrando Conversores JSF

Quais as duas alternativas para registrar um conversor a uma classe específica?

  • Usando a anotação @FacesConverter:
@FacesConverter(forClass=Estado.class)
public class EstadoConverter implements Converter {
    // ... implementação
}
  • Via faces-config.xml:
<converter>
    <converter-for-class>com.exemplo.model.Estado</converter-for-class>
    <converter-class>com.exemplo.EstadoConverter</converter-class>
</converter>

Com essa abordagem, não é preciso mencionar o conversor explicitamente no XHTML. Ele será usado automaticamente sempre que uma referência de valor for do tipo Estado.

10. Criando um Validador de E-mail JSF

Crie o seu próprio validador de e-mail.

Classe Java Bean: EmailValidador.java

@FacesValidator("com.exemplo.ValidadorDeEmail")
@ManagedBean // Nota: @FacesValidator não precisa de @ManagedBean
public class EmailValidator implements Validator {

    private String email;

    @Override
    public void validate(FacesContext facesContext, UIComponent uIComponent, Object object) throws ValidatorException {
        email = (String) object;
        Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
        Matcher m = p.matcher(email);
        boolean matchFound = m.matches();

        if (!matchFound) {
            FacesMessage message = new FacesMessage();
            message.setDetail("E-mail incorreto!");
            message.setSummary("E-mail incorreto!");
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(message);
        }
    }

    public String teste() {
        return "";
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

Página XHTML: pagina.xhtml

<h:body>
    <h:messages />
    <h:form id="form-email">
        <h:panelGrid columns="2">
            <h:outputLabel for="email" value="E-mail:" />
            <h:inputText id="email" value="#{emailValidator.email}" size="60">
                <f:validator validatorId="com.exemplo.ValidadorDeEmail" />
            </h:inputText>
        </h:panelGrid>
        <h:commandButton value="Testar" action="#{emailValidator.teste}" />
    </h:form>
</h:body>

11. Exemplo JSF: Formulário de Login com Validação

Escreva uma aplicação JSF de login de usuário com os seguintes campos e restrições:

  • Nome: deve ser um campo obrigatório, conter apenas letras minúsculas de a à z, e o máximo de 10 caracteres.
  • Senha: deve ser um campo obrigatório, conter apenas letras minúsculas e maiúsculas de a à z e números de 0 à 9, com no mínimo 8 e o máximo de 10 caracteres.

Obs.: As mensagens de erro de validação dos campos devem ser customizadas.

Classe Java Bean: LoginUsuario.java

@ManagedBean(name="lu")
@SessionScoped
public class LoginUsuario {

    private String nome;
    private String senha;

    // Construtor padrão necessário para ManagedBean
    public LoginUsuario() {
    }

    // Construtor original (mantido, mas o padrão é usado pelo JSF)
    public LoginUsuario(String nome, String senha) {
        this.nome = nome;
        this.senha = senha;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    // Método de ação para o botão de login (exemplo)
    public String logar() {
        // Lógica de autenticação aqui
        System.out.println("Tentativa de login com Nome: " + nome + ", Senha: " + senha);
        // Retornar a página de destino (ex: "sucesso.xhtml")
        return ""; // Ou uma string de navegação
    }
}

Página XHTML: loginUsuario.xhtml

<h:body>
    <h:messages />
    <h:form id="form-login">
        <h:panelGrid columns="3">
            <h:outputLabel for="campo-nome" value="Nome:" />
            <h:inputText id="campo-nome" value="#{lu.nome}"
                         label="Nome" required="true" requiredMessage="O nome é obrigatório"
                         validatorMessage="O nome deve conter letras minúsculas de a à z, e o máximo de 10 caracteres">
                <f:validateLength maximum="10" />
                <f:validateRegex pattern="[a-z]*" />
            </h:inputText>
            <h:message for="campo-nome" />

            <h:outputLabel for="campo-senha" value="Senha:" />
            <h:inputSecret id="campo-senha" value="#{lu.senha}"
                           label="Senha" required="true" requiredMessage="A senha é obrigatória"
                           validatorMessage="A senha deve conter letras minúsculas e maiúsculas de a à z, e números de 0 à 9, com no mínimo 8 e o máximo de 10 caracteres.">
                <f:validateLength minimum="8" maximum="10" />
                <f:validateRegex pattern="[a-zA-Z]*[0-9]+" />
            </h:inputSecret>
            <h:message for="campo-senha" />
        </h:panelGrid>
        <h:commandButton value="Cadastrar" action="#{lu.logar}" />
    </h:form>
</h:body>

Entradas relacionadas: