Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

Capítulo 3. Desenvolvendo Aplicativos Usando o JBoss EAP

3.1. Visão Geral

Este guia fornece informações sobre o desenvolvimento de aplicativos usando o Red Hat JBoss Developer Studio e exemplos de início rápido do JBoss EAP 7.

O Red Hat JBoss Developer Studio é um ambiente de desenvolvimento integrado (IDE) baseado em Eclipse que integra plug-ins do JBoss para o desenvolvimento de aplicativos. O JBoss Developer Studio pode ajudar no desenvolvimento de seu aplicativo com seus assistentes específicos ao JBoss e a habilidade de implantar aplicativos nos servidores do JBoss. Muitos exemplos de código de início rápido são fornecidos com o JBoss EAP 7 para auxiliar os usuários a começar a escrever os aplicativos usando diferentes tecnologias Java EE 7.

3.2. Configurando o Ambiente de Desenvolvimento

É recomendável usar o JBoss Developer Studio 11.0 ou posterior com o JBoss EAP 7.1.

  1. Faça download e instale o JBoss Developer Studio.

    Para obter instruções, consulte Instalação do JBoss Developer Studio autônomo usando o instalador no Guia de instalação do JBoss Developer Studio.

  2. Configure o servidor do JBoss EAP no JBoss Developer Studio.

    Para obter instruções, consulte Uso de detecção de tempo de execução para configurar o JBoss EAP de dentro do IDE no guia Introdução às ferramentas do JBoss Developer Studio.

3.3. Usando os Exemplos de Início Rápido

Os exemplos de início rápido fornecidos com o JBoss EAP são projetos Maven.

3.3.1. Sobre o Maven

O Apache Maven é uma ferramenta de automação de compilação distribuída, usada no desenvolvimento de aplicativos Java para criar, gerenciar e compilar projetos de software. O Maven utiliza arquivos de configuração padrão chamados POM (Modelo de Objeto do Projeto) para definir os projetos e gerenciar o processo de compilação. Os arquivos POM descrevem o módulo e as dependências dos componentes, a ordem de compilação e as metas para a saída e o empacotamento do projeto resultante usando um arquivo XML. Isto garante que o projeto seja compilado de forma correta e uniforme.

O Maven é capaz de atingir isto usando um repositório. Um repositório do Maven armazena bibliotecas Java, plug-ins e outros artefatos de compilação. O repositório público padrão é o Repositório Central do Maven 2, mas os repositórios podem ser privados e internos dentro de uma empresa com o objetivo de compartilhar artefatos comuns entre as equipes de desenvolvimento. Os repositórios também estão disponíveis através de terceiros. Para mais informações, consulte o projeto Apache Maven e o guia Introduction to Repositories.

O JBoss EAP inclui um repositório do Maven que contém muitos dos requisitos que os desenvolvedores Java EE geralmente usam para compilar aplicativos no JBoss EAP.

Para obter mais informações sobre como usar o Maven com o JBoss EAP, consulte Uso do Maven com o JBoss EAP no Guia de desenvolvimento do JBoss EAP.

3.3.2. Usando Maven com os Inícios Rápidos

As dependências e os artefatos necessários para compilar e implantar aplicativos no JBoss EAP 7 são hospedados em um repositório público. Com o JBoss EAP 7, não é mais necessário configurar o arquivo do Maven settings.xml para usar esses repositórios durante a compilação dos inícios rápidos. Os repositórios do Maven agora são configurados nos arquivos POM dos projetos de início rápido. Este método de configuração é fornecido para facilitar a introdução dos inícios rápidos, no entanto, não é geralmente recomendado para projetos de produção, pois pode deixar a sua compilação mais lenta.

O Red Hat JBoss Developer Studio inclui o Maven, portanto não há necessidade de baixá-lo e instalá-lo separadamente. É recomendável usar o JBoss Developer Studio versão 11.0 ou posterior.

Se você planeja usar a linha de comando do Maven para compilar e implantar seus aplicativos, então você deve baixar primeiro o Maven através do projeto Apache Maven e instalá-lo seguindo as instruções fornecidas na documentação do Maven.

3.3.3. Baixando e Executando os Inícios Rápidos

3.3.3.1. Baixando os Inícios Rápidos

O JBoss EAP vem com um conjunto completo de exemplos de código de início rápido criado para ajudar os usuários a começar a escrever aplicativos usando as várias tecnologias Java EE 7. Os inícios rápidos podem ser baixados a partir do Portal do Cliente Red Hat.

  1. Faça o login no Portal do Cliente Red Hat.
  2. Clique em Downloads.
  3. Na lista Downloads de Produtos, clique em Red Hat JBoss Enterprise Application Platform.
  4. Selecione 7.1 no menu suspenso Versão.
  5. Encontre a entrada Red Hat JBoss Enterprise Application Platform 7.1.0 Quickstarts na tabela e clique em Download.
  6. Salve o arquivo ZIP no diretório desejado.
  7. Extraia o arquivo ZIP.

3.3.3.2. Executando os Inícios Rápidos no JBoss Developer Studio

Depois que os inícios rápidos foram baixados, eles podem ser importados no JBoss Developer Studio e implantados no JBoss EAP.

Importando um Início Rápido para o JBoss Developer Studio

Cada início rápido é fornecido com um arquivo POM que contém o seu projeto e informações de configuração. Use este arquivo POM para importar com facilidade o início rápido para o Red Hat JBoss Developer Studio.

Importante

Caso a sua pasta do projeto de início rápido esteja localizada no espaço de trabalho do IDE, quando você importá-la no Red Hat JBoss Developer Studio, o IDE gera um nome de arquivo WAR e um nome de projeto inválido. Certifique-se antes de que a sua pasta do projeto de início rápido esteja localizada fora do espaço de trabalho do IDE.

  1. Inicie o JBoss Developer Studio.
  2. Selecione ArquivoImportar.
  3. Selecione MavenProjetos Maven Existentes e clique em Next.

    Figura 3.1. Importando Projetos Maven Existentes

    The *Import* window.
  4. Navegue até o diretório do início rápido desejado (por exemplo, o início rápido helloworld) e clique em OK. A caixa de listagem dos Projetos é preenchida pelo arquivo pom.xml do projeto de início rápido selecionado.

    Figura 3.2. Selecionando Projetos Maven

    The *Maven Projects* selection window.
  5. Clique em Concluir.

Executando o Início Rápido helloworld

A execução do início rápido helloworld é uma maneira simples de verificar se o servidor do JBoss EAP está configurado e executando corretamente.

  1. Se você ainda não definiu um servidor, adicione o servidor do JBoss EAP ao JBoss Developer Studio. Consulte Uso da detecção de tempo de detecção para configurar o JBoss EAP de dentro do IDE no guia Introdução às ferramentas do JBoss Developer Studio.
  2. Clique com o botão direito do mouse no projeto helloworld na guia Explorador de projeto e selecione Executar comoExecutar no servidor.

    Figura 3.3. Executar Como - Executar no Servidor

    The *Run As* -> *Run on Server* screen capture.
  3. Selecione o servidor do JBoss EAP 7.1 na lista de servidores e clique em Próximo.

    Figura 3.4. Executar no Servidor

    The *Run on Server* window.
  4. O início rápido helloworld já está listado para ser configurado no servidor. Clique em Concluir para implantar o início rápido.

    Figura 3.5. Modificando os Recursos Configurados no Servidor

    The *Add and Remove Resources* window.
  5. Verifique os resultados.

    • Na guia Servidor, o status do servidor do JBoss EAP 7.1 muda para Iniciado .
    • A guia Console mostra as mensagens detalhando a inicialização do servidor do JBoss EAP e a implantação do início rápido helloworld.

      WFLYUT0021: Registered web context: /helloworld
      WFLYSRV0010: Deployed "helloworld.war" (runtime-name : "helloworld.war")
    • O aplicativo helloworld está disponível em http://localhost:8080/helloworld e exibe o texto Hello World!.

Para obter detalhes adicionais sobre o início rápido helloworld, consulte Exploração do início rápido helloworld.

Executando o Início Rápido bean-validation

Alguns inícios rápidos, tais como o bean-validation, não fornecem a camada da interface do usuário e, em vez disto, fornecem testes Arquillian para demonstrar funcionalidade.

  1. Importe o início rápido bean-validation no JBoss Developer Studio.
  2. Na guia Servidores, clique com o botão direito no servidor e escolha Iniciar para iniciar o servidor do JBoss EAP. Se você não encontrar uma guia Servidores ou ainda não tiver definido um servidor, adicione o servidor do JBoss EAP ao JBoss Developer Studio. Consulte Uso de detecção de tempo de execução para configurar o JBoss EAP de dentro do IDE no guia Introdução às ferramentas do JBoss Developer Studio.
  3. Clique com o botão direito do mouse no projeto jboss-bean-validation na guia Explorador de projeto e selecione Executar comoCompilação do Maven.
  4. Insira o seguinte no campo de entrada Metas e clique em executar.

    clean verify -Parq-remote

    Figura 3.6. Editando a Configuração

    The *Edit Configuration* window.
  5. Verifique os resultados.

    A guia Console mostra os resultados dos testes Arquillian do bean-validation:

    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running org.jboss.as.quickstarts.bean_validation.test.MemberValidationTest
    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.189 sec
    
    Results :
    
    Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
    
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------

3.3.3.3. Executando os Inícios Rápidos através da Linha de Comando

Você pode compilar e implantar facilmente os inícios rápidos através da linha de comando usando o Maven. Se você ainda não instalou o Maven, consulte o projeto Apache Maven para baixá-lo e instalá-lo.

O arquivo README.md é fornecido no diretório raiz dos inícios rápidos e contém informações gerais sobre as exigências do sistema, configuração do Maven, adição de usuários e execução de inícios rápidos.

Cada início rápido também contém o seu próprio arquivo README.md que fornece instruções específicas e comandos do Maven para executar esse início rápido.

Executando o Início Rápido helloworld através da Linha de Comando

  1. Revise o arquivo README.md no diretório raiz do início rápido helloworld.
  2. Inicie o servidor do JBoss EAP.

    $ EAP_HOME/bin/standalone.sh
  3. Navegue até o diretório de início rápido helloworld.
  4. Compile e implante o início rápido usando o comando do Maven fornecido no arquivo README.md do início rápido.

    $ mvn clean install wildfly:deploy
  5. O aplicativo helloworld está disponível agora em http://localhost:8080/helloworld e exibe o texto Hello World!.

3.4. Revise os exemplos de início rápido

3.4.1. Explorando a Inicialização Rápida helloworld

O início rápido helloworld mostra como implantar um servlet simples no JBoss EAP. A lógica comercial é encapsulada em um serviço, que é fornecido como um bean de contextos e injeção de dependência (CDI) e injetado no Servlet. Esse início rápido é um ponto de partida para garantir que você configurou e iniciou o servidor adequadamente.

Instruções detalhadas para compilação e implantação desse início rápido usando a linha de comando podem ser encontradas no arquivo README.html na raiz do diretório do início rápido helloworld. Este tópico mostra como usar o Red Hat JBoss Developer Studio para executar o início rápido e presume que você instalou o Red Hat JBoss Developer Studio, configurou o Maven e importou e executou com êxito o início rápido helloworld.

Pré-requisitos
Examine a Estrutura do Diretório

O código do início rápido helloworld pode ser encontrado no diretório QUICKSTART_HOME/helloworld/. O início rápido helloworld é composto por um Servlet e um bean CDI. Ele também contém um arquivo beans.xml no diretório WEB-INF/ do aplicativo que tem um número de versão 1.1 e um bean-discovery-mode de all. Esse arquivo de marcador identifica o WAR como um arquivo morto bean e informa ao JBoss EAP para procurar por beans no aplicativo e ativar a CDI.

O diretório src/main/webapp/ contém os arquivos do início rápido. Todos os arquivos de configuração deste exemplo estão localizados no diretório WEB-INF/ em src/main/webapp/, inclusive o arquivo beans.xml. O diretório src/main/webapp/ também inclui um arquivo index.html, que usa uma atualização meta simples para redirecionar o navegador do usuário para o Servlet, que está localizado em http://localhost:8080/helloworld/HelloWorld. O início rápido não exige um arquivo web.xml.

Examine o Código

A declaração e importações do pacote foram excluídas destas listagens. A listagem completa está disponível no código de fonte da inicialização rápida.

  1. Revise o código do HelloWorldServlet.

    O arquivo HelloWorldServlet.java está localizado no diretório src/main/java/org/jboss/as/quickstarts/helloworld/. Este servlet envia as informações ao navegador.

    Exemplo: código de classe do HelloWorldServlet

    42 @SuppressWarnings("serial")
    43 @WebServlet("/HelloWorld")
    44 public class HelloWorldServlet extends HttpServlet {
    45
    46     static String PAGE_HEADER = "<html><head><title>helloworld</title></head><body>";
    47
    48     static String PAGE_FOOTER = "</body></html>";
    49
    50     @Inject
    51	   HelloService helloService;
    52
    53     @Override
    54     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    55         resp.setContentType("text/html");
    56         PrintWriter writer = resp.getWriter();
    57         writer.println(PAGE_HEADER);
    58         writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
    59         writer.println(PAGE_FOOTER);
    60         writer.close();
    61     }
    62
    63 }

    Tabela 3.1. Detalhes do HelloWorldServlet

    LinhaObservação

    43

    Basta adicionar a anotação @WebServlet e fornecer um mapeamento para um URL usado para acessar o servlet.

    46-48

    Cada página da web precisa HTML corretamente formado. Essa inicialização rápida usa Sequências estáticas para gravar o resultado de rodapé e cabeçalho mínimo.

    50-51

    Estas linhas injetam o bean CDI do HelloService que gera a mensagem real. Contanto que a API do HelloService não seja alterada, esta abordagem permite alterar a implementação do HelloService em uma data posterior sem modificar a camada de exibição.

    58

    Esta linha chama o serviço para gerar a mensagem "Hello World" e gravá-la à solicitação HTTP.

  2. Revise o código do HelloService.

    O arquivo HelloService.java está localizado no diretório src/main/java/org/jboss/as/quickstarts/helloworld/. Este serviço simplesmente retorna uma mensagem. Não é necessário nenhum XML ou registro de anotação.

    Exemplo: código de classe do HelloService

    public class HelloService {
    
        String createHelloMessage(String name) {
            return "Hello " + name + "!";
        }
    }

3.4.2. Explorando a Inicialização Rápida do numberguess (adivinhação de número)

O início rápido numberguess mostra como criar e implantar um aplicativo não persistente simples no JBoss EAP. As informações são exibidas usando uma exibição JSF e a lógica comercial é encapsulada em dois beans CDI. No início rápido numberguess, você tem dez tentativas para adivinhar um número entre 1 e 100. Depois de cada tentativa, você será informado se o número foi muito alto ou muito baixo.

O código do início rápido numberguess pode ser encontrado no diretório QUICKSTART_HOME/numberguess/, em que QUICKSTART_HOME é o diretório em que você baixou e descompactou os inícios rápidos do JBoss EAP. O início rápido numberguess é composto por alguns beans, arquivos de configuração e exibições Facelets (JSF) e é empacotado como um módulo WAR.

Instruções detalhadas para compilação e implantação desse início rápido usando a linha de comando podem ser encontradas no arquivo README.html na raiz do diretório do início rápido numberguess. Os exemplos a seguir usam o Red Hat JBoss Developer Studio para executar o início rápido.

Pré-requisitos
Examinando os Arquivos de Configuração

Todos os arquivos de configuração deste exemplo estão localizados no diretório QUICKSTART_HOME/numberguess/src/main/webapp/WEB-INF/ do início rápido.

  1. Examine o arquivo faces-config.xml.

    Este início rápido usa a versão JSF 2.2 do nome de arquivo faces-config.xml. Uma versão padronizada do Facelets é o manipulador d exibição padrão no JSF 2.2 e, portanto, não requer configuração. Esse arquivo consiste em apenas o elemento raiz e é simplesmente um arquivo de marcador para indicar que o JSF deve ser habilitado no aplicativo.

    <faces-config version="2.2"
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
    
    </faces-config>
  2. Examine o arquivo beans.xml.

    O arquivo beans.xml contém um número de versão 1.1 e um bean-discovery-mode de all. Esse arquivo é um arquivo de marcador que identifica o WAR como um arquivo morto de bean e informa ao JBoss EAP para procurar por beans no aplicativo e ativar a CDI.

    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
          http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        bean-discovery-mode="all">
    </beans>
Nota

Este início rápido não precisa de um arquivo web.xml.

3.4.2.1. Examinando o código JSF

O JSF usa a extensão de arquivo .xhtml para arquivos de fonte, mas fornece as exibições renderizadas com a extensão .jsf. O arquivo home.xhtml está localizado no diretório src/main/webapp/.

Exemplo: código-fonte do JSF

19<html xmlns="http://www.w3.org/1999/xhtml"
20	xmlns:ui="http://java.sun.com/jsf/facelets"
21	xmlns:h="http://java.sun.com/jsf/html"
22	xmlns:f="http://java.sun.com/jsf/core">
23
24	<head>
25	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
26	<title>Numberguess</title>
27	</head>
28
29	<body>
30	<div id="content">
31		<h1>Guess a number...</h1>
32		<h:form id="numberGuess">
33
34		<!-- Feedback for the user on their guess -->
35	<div style="color: red">
36		<h:messages id="messages" globalOnly="false" />
37		<h:outputText id="Higher" value="Higher!"
38 		  rendered="#{game.number gt game.guess and game.guess ne 0}" />
39		<h:outputText id="Lower" value="Lower!"
40		   rendered="#{game.number lt game.guess and game.guess ne 0}" />
41	</div>
42
43	<!-- Instructions for the user -->
44	<div>
45	I'm thinking of a number between <span
46	id="numberGuess:smallest">#{game.smallest}</span> and <span
47	id="numberGuess:biggest">#{game.biggest}</span>. You have
48	#{game.remainingGuesses} guesses remaining.
49	</div>
50
51	<!-- Input box for the users guess, plus a button to submit, and reset -->
52	<!-- These are bound using EL to our CDI beans -->
53	<div>
54	Your guess:
55	<h:inputText id="inputGuess" value="#{game.guess}"
56		required="true" size="3"
57		disabled="#{game.number eq game.guess}"
58		validator="#{game.validateNumberRange}" />
59		<h:commandButton id="guessButton" value="Guess"
60			action="#{game.check}"
61			disabled="#{game.number eq game.guess}" />
62	</div>
63	<div>
64	<h:commandButton id="restartButton" value="Reset"
65	action="#{game.reset}" immediate="true" />
66	</div>
67	</h:form>
68
69	</div>
70
71	<br style="clear: both" />
72
73	</body>
74</html>

Os seguintes números de linha correspondem àqueles vistos ao visualizar o arquivo no JBoss Developer Studio.

Tabela 3.2. Detalhes do JSF

LinhaObservação

36-40

Essas são as mensagens que podem ser enviadas ao usuário: "Maior!" e "Menor!"

45-48

Assim que o usuário vai adivinhando, a variedade de número de número que ele pode adivinhar vai reduzindo. Esta sentença é alterada para certificação de que um usuário sabe a variedade de número de uma adivinhação válida.

55-58

Este campo de entrada é vinculado a uma propriedade de bean usando uma expressão de valor.

58

Uma associação de validador é usada para garantir que o usuário não informe acidentalmente um número fora do intervalo para adivinhação. Se o validador não estivesse presente, o usuário poderia desperdiçar uma tentativa com um número fora dos limites.

59-61

Deve haver uma maneira do usuário enviar sua tentativa de adivinhação ao servidor. Aqui nós vinculamos um método de ação no bean.

3.4.2.2. Examinação nos Arquivos de Classe

Todos os arquivos de fonte do início rápido numberguess podem ser encontrados no diretório QUICKSTART_HOME/numberguess/src/main/java/org/jboss/as/quickstarts/numberguess/. A declaração e as importações do pacote foram excluídas dessas listagens. A listagem completa está disponível no código-fonte do início rápido.

  1. Revise o código do qualificador Random.java

    Um qualificador é usado para remover a ambiguidade entre dois beans, ambos elegíveis para injeção com base no tipo. Para obter mais informações sobre qualificadores, consulte Uso de um qualificador para resolver uma injeção ambígua no Guia de desenvolvimento do JBoss EAP. O qualificador @Random é usado para injetar um número aleatório.

    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface Random {
    
    }
  2. Revise o código do qualificador MaxNumber.java

    O qualificador @MaxNumber é usado para injetar o número máximo permitido.

    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface MaxNumber {
    }
  3. Revise o código de Generator.java

    A classe Generator cria um número aleatório por meio de um método produtor, expondo o número máximo possível por meio dele. Essa classe está no escopo do aplicativo, então você não obterá um aleatório diferente a cada vez.

    @SuppressWarnings("serial")
    @ApplicationScoped
    public class Generator implements Serializable {
    
        private java.util.Random random = new java.util.Random(System.currentTimeMillis());
    
        private int maxNumber = 100;
    
        java.util.Random getRandom() {
            return random;
        }
    
        @Produces
        @Random
        int next() {
            // a number between 1 and 100
            return getRandom().nextInt(maxNumber - 1) + 1;
        }
    
        @Produces
        @MaxNumber
        int getMaxNumber() {
            return maxNumber;
        }
    }
  4. Revise o código de Game.java

    A classe no escopo de sessão Game é o ponto de entrada primário do aplicativo. É responsável por configurar ou redefinir o jogo, capturar e validar a adivinhação do usuário e fornecer feedback para o usuário com um FacesMessage. Ela usa o método de ciclo de vida pós constructo para inicializar o jogo recuperando um número aleatório do bean @Random Instance<Integer>.

    Observe a anotação @Named na classe. Essa anotação só é exigida quando você desejar tornar o bean acessível a uma exibição JSF usando a linguagem de expressão (EL), neste caso, #{game}.

    @SuppressWarnings("serial")
    @Named
    @SessionScoped
    public class Game implements Serializable {
    
        /**
         * The number that the user needs to guess
         */
        private int number;
    
        /**
         * The users latest guess
         */
        private int guess;
    
        /**
         * The smallest number guessed so far (so we can track the valid guess range).
         */
        private int smallest;
    
        /**
         * The largest number guessed so far
         */
        private int biggest;
    
        /**
         * The number of guesses remaining
         */
        private int remainingGuesses;
    
        /**
         * The maximum number we should ask them to guess
         */
        @Inject
        @MaxNumber
        private int maxNumber;
    
        /**
         * The random number to guess
         */
        @Inject
        @Random
        Instance<Integer> randomNumber;
    
        public Game() {
        }
    
        public int getNumber() {
            return number;
        }
    
        public int getGuess() {
            return guess;
        }
    
        public void setGuess(int guess) {
            this.guess = guess;
        }
    
        public int getSmallest() {
            return smallest;
        }
    
        public int getBiggest() {
            return biggest;
        }
    
        public int getRemainingGuesses() {
            return remainingGuesses;
        }
    
        /**
         * Check whether the current guess is correct, and update the biggest/smallest guesses as needed. Give feedback to the user
         * if they are correct.
         */
        public void check() {
            if (guess > number) {
                biggest = guess - 1;
            } else if (guess < number) {
                smallest = guess + 1;
            } else if (guess == number) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!"));
            }
            remainingGuesses--;
        }
    
        /**
         * Reset the game, by putting all values back to their defaults, and getting a new random number. We also call this method
         * when the user starts playing for the first time using {@linkplain PostConstruct @PostConstruct} to set the initial
         * values.
         */
        @PostConstruct
        public void reset() {
            this.smallest = 0;
            this.guess = 0;
            this.remainingGuesses = 10;
            this.biggest = maxNumber;
            this.number = randomNumber.get();
        }
    
        /**
         * A JSF validation method which checks whether the guess is valid. It might not be valid because there are no guesses left,
         * or because the guess is not in range.
         *
         */
        public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) {
            if (remainingGuesses <= 0) {
                FacesMessage message = new FacesMessage("No guesses left!");
                context.addMessage(toValidate.getClientId(context), message);
                ((UIInput) toValidate).setValid(false);
                return;
            }
            int input = (Integer) value;
    
            if (input < smallest || input > biggest) {
                ((UIInput) toValidate).setValid(false);
    
                FacesMessage message = new FacesMessage("Invalid guess");
                context.addMessage(toValidate.getClientId(context), message);
            }
        }
    }