Para criar um novo projeto, vá no Netbeans em Java Web e em Aplicação Web, e selecione o Apache Tomcat (ou o Glass Fish), e nos frameworks, não escolha a opção JavaServerFaces. Observe que nas bibliotecas, deverá estar além do JDK, a biblioteca do servido (no caso, o Apache Tomcat) e o JSF 2.2 API e IMPL, que podem ser baixados daqui: http://www.java2s.com/Code/Jar/j/Downloadjsfapi219jar.htm e http://www.java2s.com/Code/Jar/j/Downloadjsfimpl219jar.htm
Dessa forma, ele executará como página principal a index.xhtml. Os arquivos XHTML são a fusão de XML com HTML, e são muito utilizados em Java Web.
Basicamente, a diferença entre um arquivo XHTML e de um HTML comum, é o fato de no começo, ter um bloco de indicação de XML, e na tag principal do HTML, ter a indicação do link do XML com o xmlns (XML attributes), dessa forma:
<?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://xmlns.jcp.org/jsf/html">
No entanto, é comum encontrarmos as tags em XHTML assim, devido ao xmlns adicionado com o h:
<h:head>
</h:head>
<h:body>
</h:body>
Observe que, nos arquivos, terão os arquivos na Página Web, que os arquivos do site tem que serão os mesmos dos arquivos de configuração, para não dar erros como os de CSS. Para o CSS do Apache Tomcat não sobreescrever o CSS do projeto, veja a pasta web dentro do build, que deverão ser os mesmos arquivos da pasta web, isso vale pro favicon e outros arquivos.
Para continuarmos, vamos salvar o Primefaces no nosso projeto, baixando ele nesse link (baixe a versão 5, não a versão 6 ou superior): https://jitpack.io/p/primefaces/primefaces
Crie, no local dos arquivos do site (na mesma onde encontramos o nbproject, web e src), e salve o jar do Primefaces lá, e nas propriedades do site, em bibliotecas, vá em adicionar JAR/Pasta, adicione o JAR (não adicione a pasta, só o JAR dele).
E no código HTML, adicione o link do XML do Primefaces assim: xmlns:p="http://primefaces.org/ui"
Coloque um botão assim no XHTML:
<p:button value="Enviar"></p:button>
O botão já tem um estilo próprio devido a biblioteca do Primefaces.
Abra também uma tag p:panelGrid com o atributo columns de valor 2, e coloque o button dentro dele.
Abra dentro do panelGrid, um h:outputLabel, com for indiciando a id nome e o value Nome, e abaixo dele, um p:inputText com a id nome.
PS: o paneGrid funciona de forma parecida com as tabelas, assim como o outputLabel funciona de forma parecida com o label e asim por diante.
Esse seria o código criados dessa forma, veja abaixo:
<h:form>
<p:panelGrid columns="2">
<h:outputLabel for="nome" value="Nome"></h:outputLabel>
<p:inputText id="nome"></p:inputText>
<h:outputLabel for="sobrenome" value="Sobrenome"></h:outputLabel>
<p:inputText id="sobrenome"></p:inputText>
<p:button value="Enviar"></p:button>
</p:panelGrid>
</h:form>
Existem várias tags que podemos usar com Primefaces, como a p:spinner, para valores numéricos. Temos também o f:convertNumber para convertermos números para, por exemplo, valor monetário.
PS: Para bloquear o acesso às páginas xhtml (de forma que se acesse apenas ao resultado jsf delas), abra o arquivo web.xml dentro de WEB-INF e adicione esse código dentro da tag web-app, logo abaixo da tag servlet:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>Restrict raw XHTML Documents</display-name>
<web-resource-collection>
<web-resource-name>XHTML</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
Caso não ache o arquivo web.xml, copie ele do diretório onde está instalado o Apache, em webapps/ROOT/WEB-INF.
Se o programa não rodar, exclua o arquivo xml localizado em conf\Catalina\localhost e a pasta localizada em work\Catalina\localhost com o nome do projeto, dentro do diretório onde o Apache Tomcat está instalado.
PS: Para o CSS do Apache Tomcat não sobreescrever o CSS do projeto, veja a pasta web dentro do build, que deverão ser os mesmos arquivos da pasta web, isso vale pro favicon e outros arquivos.
Para excluir a favicon padrão do Apache, exclua ele na pasta webapps/ROOT
Por padrão, o Netbeans pede como senha do Apache Tomcat o Login "tomcat" e a senha "admin", para alterar a senha, altere o arquivo tomcat80 (no Windows é localizado em AppData\Roaming\Netbeans\8.2\). Não esqueça de configurar a senha no arquivo tomcat-users.xml (localizado na pasta conf do Apache).
Para executar o servidor Tomcat sem abrir o Netbeans, execute o arquivo startup.bat em Windows ou startup.sh no Linux, e mantenha ele executando. Para interromper o funcionamento basta interromper a execução do script. Quando for colocar o site no ar, coloqueo arquivo WAR dentro da pasta WEBAPPS do Tomcat.
PS: A partir da versão 10 do Apache Tomcat, os pacotes javax.faces.*
foram substituídos por jakarta.faces.*
. Ele necessitará desses Jars aqui, no caso:
Nessa aula criaremos o Managed Bean, que é o código Java que servirá para auxiliar na criação das telas do JSF, ou seja, intermediará os códigos Java e XML, como por exemplo, ao criar ações para botões e passar dados pro Java.
Nos pacotes de código-fonte, crie um pacote Java chamado beans e dentro dele uma classe com o nome NomesBean, e coloque esse código:
package beans;
import javax.faces.bean.ManagedBean;
@ManagedBean // Anotação que deve ser importada de javax.faces.bean.ManagedBean
public class NomesBean {
}
Na anotação ManagerBean, que indicará o uso do mesmo, ele sempre gerará um name pro XHTML igual o da classe, apesar de ser configurável dentro do Java (utilizando @ManagedBean(name = "nomeNovo")
).
Devemos também colocar uma anotação de escopo de sessão, que definirá o tempo de sessão do nosso site, ou seja, o tempo que a classe ficará na memória do nosso site. Veja o uso abaixo:
package beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@SessionScoped // Anotação que deve ser importada de javax.faces.bean.SessionScoped
@ManagedBean
public class NomesBean {
}
Observe que no arquivo web.xml, em WEB-INF, tem uma tág session-timeout, que define o tempo de encerramento de sessões em minutos, sem mexer em nada dentro do site (um exemplo disso é os sistemas bancários, que encerram o acesso dentro de alguns minutos sem mexer o site, até por segurança, um dos motivos dos sites de bancos serem em Java.
Esse é o código completo, com os métodos getters e setters:
package beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@SessionScoped
@ManagedBean
public class NomesBean {
private String nome;
private String sobrenome;
private String mensagem;
public void dizerOla() {
mensagem = "Olá, " + nome + " " + sobrenome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getSobrenome() {
return sobrenome;
}
public void setSobrenome(String sobrenome) {
this.sobrenome = sobrenome;
}
public String getMensagem() {
return mensagem;
}
public void setMensagem(String mensagem) {
this.mensagem = mensagem;
}
}
Para chamar os elementos do Java no XHTML, abra um atributo value, e dentro dele uma hashtag com chaves, e dentro dele o nome do managerBean (mesmo nome da classe, só que com a primeira minúscula), acompanhados dos métodos ou atributos desejados da classe, dessa forma:
<p:inputText id="nome" value="#{nomesBean.nome}"></p:inputText>
Faça o mesmo no sobrenome.
Só que, para podermos enviar dados pro Java, o panelGrid todo, com todos os elementos, deverão estar no meio de tags h:form.
E para enviarmos os dados, precisaremos usar o p:commandButton ao invés do button, com o bean e a função, dessa forma:
<p:commandButton value="Enviar" action="#{nomesBean.dizerOla()}" update="msg"></p:commandButton>
PS: O Update impede que tenhamos que carregar a página para executar o processo, isso é possível graças ao Ajax.
E para exibir, usaremos o h:outputText assim:
<h:outputText id="msg" value="#{nomesBean.mensagem}"></h:outputText>
Lembrando que temos que recompilar os arquivos Java ao fazer alterações no Java (não é necessário quando alteramos apenas o XHTML). Assim como o PHP, os códigos Java não são visíveis do lado cliente, sendo totalmente interpretados pelo servidor (que tem uma JVM integrada), o que dispensa o usuário de ter Java instalado no PC para acessar. Uma coisa que torna o Java mais seguro, é o fato dele ser compilado, e não interpretado, por isso é mais seguro para sites como os de banco e do governo, pelo fato dos hackers não poderem ter acesso ao código-fonte.
PS: A maioria das classes de pacotes padrões usadas no Java funcionam em web, mas algumas não funcionam por conter código exclusivamente para aplicações Java desktop, como por exemplo:
Pacotes e Classes do Java 8 |
---|
java.util.Scanner |
java.awt.* |
javax.swing.* |
javafx.* |
No entanto, temos vários pacotes usados exclusivamente na web.
Exclua o formulário da aula anterior e abra uma tag p:fieldset com o legend Objetos
Crie uma classe com o nome Carro (num outro pacote só pra classes), que terá esse código:
package classes;
public class Carro {
private Integer id;
private String modelo;
private String fabricante;
private String cor;
private String ano;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getModelo() {
return modelo;
}
public void setModelo(String modelo) {
this.modelo = modelo;
}
public String getFabricante() {
return fabricante;
}
public void setFabricante(String fabricante) {
this.fabricante = fabricante;
}
public String getCor() {
return cor;
}
public void setCor(String cor) {
this.cor = cor;
}
public String getAno() {
return ano;
}
public void setAno(String ano) {
this.ano = ano;
}
}
PS: A classe invólucro Integer é mais interessante por manter o valor "null", diferente do tipo int que o padrão é 0.
E para o Bean, crie uma classe com o nome CarroBean, no pacote beans:
package beans;
import classes.Carro;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@SessionScoped
@ManagedBean
public class CarroBean {
private Carro car = new Carro();
private List<Carro> carros = new ArrayList<>();
public void adicionar() {
carros.add(car);
car = new Carro();
}
public Carro getCar() {
return car;
}
public void setCar(Carro car) {
this.car = car;
}
public List<Carro> getCarros() {
return carros;
}
public void setCarros(List<Carro> carros) {
this.carros = carros;
}
}
E no gerenciar-carro.xhtml, crie essa estrutura:
<h:form>
<p:fieldset legend="Objetos">
<p:toolbarGroup>
<p:commandButton value="Adicionar" action="#{carroBean.adicionar()}" update="@form"></p:commandButton>
</p:toolbarGroup>
<p:panelGrid columns="2">
<h:outputLabel value="Modelo"></h:outputLabel>
<p:inputText value="#{carroBean.car.modelo}"></p:inputText>
<h:outputLabel value="Fabricante"></h:outputLabel>
<p:inputText value="#{carroBean.car.fabricante}"></p:inputText>
<h:outputLabel value="Cor"></h:outputLabel>
<p:inputText value="#{carroBean.car.cor}"></p:inputText>
<h:outputLabel value="Ano"></h:outputLabel>
<p:inputMask mask="9999" value="#{carroBean.car.ano}"></p:inputMask>
</p:panelGrid>
<p:dataTable value="#{carroBean.carros}" var="carroForm">
<p:column headerText="Modelo" sortBy="#{carroForm.modelo}">
<h:outputText value="#{carroForm.modelo}"></h:outputText>
</p:column>
<p:column headerText="Fabricante">
<h:outputText value="#{carroForm.fabricante}"></h:outputText>
</p:column>
<p:column headerText="Cor">
<h:outputText value="#{carroForm.cor}"></h:outputText>
</p:column>
<p:column headerText="Ano">
<h:outputText value="#{carroForm.ano}"></h:outputText>
</p:column>
</p:dataTable>
</p:fieldset>
</h:form>
PS: Observe que criamos uma variável local em dataTable, com o atributo var. O sortBy nas colunas define a ordenação dos elementos.