Camada de controlo no JSF
No workflow para a programação com JavaServer Faces, um dos itens indicados é a criação dos CDI Managed Beans. Será o item será apresentado com detalhe num capitulo a parte. Mas em função do esquema de construção que está a ser seguido é feita já uma breve apresentação.
É importante partir da consideração de que uma dos aspetos importantes no desenho das aplicações Web, nos dias de hoje, é a clara separação entre a camada de apresentação e a camada da lógica de negócio. O JavaServer Faces utiliza os beans para garantir esta separação.
As páginas a aplicação são ligadas às propriedades dos beans, e os elementos do Model do MVC são contidos no código de implementação do Managed Bean. De lembrar que o Model compreende todo o back-end ou seja as regras de negócios e os processos ou regras de acesso aos dados.
Os Managed Beans, como já dito, representam o Model do padrão de arquitetura MVC, mas podem ter as funcionalidades do Controller pois podem armazenar os dados a mostrar na View ou receber os dados da entrado do utilizador. E ainda, podem implementar a lógica da aplicação diretamente ou de forma delegada.
Os Managed Beans manejam as regras de navegação entre as paginas e podem ser partilhados por várias views.
Mas essencialmente, os Managed Beans, são classes que expões os objetos de negócio à camada de apresentação e são associados aos componentes visuais da pagina através da Expression Language no formato #{ … }.
É importante notar que no JavaServer Faces a função do Controller propriamente dita é feita de forma transparente pelo FaceServlet que é uma implementação dos Servlets para JSF e que é responsável por processar as requisições das paginas JSF e retornar a interface HTML ao utilizador da aplicação. Este item será aprofundado no capítulo sobre o Ciclo de Vida do JavaServer Faces.
Declaração de um Managed Bean
Atualmente convivem duas formas de declaração. Uma do JSF 2.0 e outra do JSF 2.2 que é mais voltado para os CDI Managed Beans.
No JSF 2.0 o Managed Beans são declarados e configurados, por padrão, com a anotação @ManegedBean do pacote javax.faces.bean.
É possível pode atribuir um nome especifico ao Managed Bean fazendo @ManagedBean (name=”nomeDoBean”). Caso não um nome não seja especificado explicitamente o JSF utiliza o nome da classe do Bean com a primeira letra minúscula.
Exemplo: classe ParticipanteMBean.java
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean(name = "participanteMBean")
@RequestScoped
public class ParticipanteMBean{
// implementação
}
No JSF 2.2, com o CDI habilitado, os Managed Beans são declarados e configurados com a anotação @Named, do pacote javax.inject.Named e devem implementar a interface Serializable.
É possível pode atribuir um nome especifico ao CDI Managed Bean fazendo @Named (”nomeDoBean”). Caso não um nome não seja especificado explicitamente o JSF utiliza o nome da classe do Bean com a primeira letra minúscula.
Exemplo: classe ParticipanteMBean.java
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
@Named(value ="participanteMBean")
@RequestScoped
public class ParticipanteMBean{
//implementação
}
Para todo o Managed Bean é necessário especificar o seu tempo e vida e alcance através dos escopos.
Os escopos para o JSF 2.0 estão disponíveis no pacote javax.faces.bean. Diferentemente, no JSF 2.2 estes estão disponíveis no pacote javax.enterprise.context.
É importante notar que a especificação e forma de declaração dos Managed Beans do JSF 2.0 está marcada como deprecated e aconselha-se a utilização dos CDI Managed Beans.
Implementação de um CDI ManagedBean
Para uma primeira exemplificação de implementação de uma pagina com JSF serão utilizados objetos de classes simples, isto é, objetos de classes sem referencia a outras, ou seja, sem composição. Como é o caso das classes CategoriaFuncionario.java, Departamento.java, TipoProjeto.java, por exemplo, do projeto em construção.
Habilitar a utilização do CDI Beans na aplicação
1. Para se poder trabalhar com os CDI beans, a primeira coisa a fazer é criar o ficheiro beans.xml. Para tal, no NetBeans, basta fazer clique com o botão direito do mouse sobre a aplicação apontar para New (Novo), apontar para Other... e na caixa de diálogo que aparece na secção Categories(Categorias) escolher Contexts and Dependency Injection e nem File Types(Tipo de ficheiros) escolher beans.xml(CDI Configuration File) e fazer clique sobre o botão Next(Seguinte).
2. O NetBeans situa o ficheiro na pasta WEB-INF. Portanto, na caixa de diálogo basta fazer clique sobre o botão Finish(Terminar).
O Ficheiro beans.xml é obrigatório quando se pretende trabalhar com os CDI Beans.
Criação do CDI Managed Bean
1. Fazer clique com o botão direito do mouse sobre a aplicação, apontar para New(Novo), apontar para Other... e na caixa de diálogo que aparecer, na secção Categories(Categorias) escolher JavaServer Faces e na secção File Types(Tipo de ficheiros) escolher JSF Managed Bean e fazer clique em Next(Seguinte).
2. Na janela seguinte deve-se definir o nome (Name) do Managed Bean, o Package onde vai ficar e o escopo (Scope). Definidos este parâmetros, fazer clique em Finish(Terminar) para concluir o processo de criação.
3. A seguir o NetBeans IDE, mostra o código do CDI Managed Bean criado no editor e pode-se então prosseguir com a implementação.
4. Continuando…
A seguir deve-se criar uma instância do JavaBeam e do DAO. Fazendo:
private Participante participante= new Participante();
private ParticipanteDAO participanteDAO = new ParticipanteDAO();
E criar os setters e getters para a instância do objeto participante da classe Participante.
Esta instaciação pode ser feita dentro de um método de inicialização com a anotação @PostConstruct como se pode ver no códico completo do CDI Bean ParticipanteMBeam.
Para mapear os métodos do CRUD, no ManagedBean devem-se ser criados os métodos que deverão interagir diretamente com as páginas e que mapeiem as regras de negócio e de acesso e operação com os dados. A seguir é mostrado o código completo do CDI Managed Bean CategoriaFuncionarioMBean.java
package org.ao.mirangol.mb;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import org.ao.mirangol.dao.MunicipioDAO;
import org.ao.mirangol.dao.ParticipanteDAO;
import org.ao.mirangol.modelo.Municipio;
import org.ao.mirangol.modelo.Participante;
import org.ao.mirangol.modelo.Sexo;
@Named(value = "participanteMBean")
@RequestScoped
public class ParticipanteMBean implements Serializable{
private static final long serialVersionUID = 1L;
private Participante participante;
private List<Sexo> sexos;
private MunicipioDAO municipioDAO;
private ParticipanteDAO participanteDAO;
private List<Municipio> municipios;
private List<Participante> participantes;
public ParticipanteMBean() {
}
@PostConstruct
public void inicializar() {
participante = new Participante();
sexos = Arrays.asList(Sexo.values());
municipioDAO = new MunicipioDAO();
participanteDAO = new ParticipanteDAO();
}
public Participante getParticipante() {
return participante;
}
public void setParticipante(Participante participante) {
this.participante = participante;
}
public List<Sexo> getSexos() {
return sexos;
}
public void setSexos(List<Sexo> sexos) {
this.sexos = sexos;
}
public Sexo[] getGeneros() {
return Sexo.values();
}
public List<SelectItem> getOpSexos() {
List<SelectItem> list = new ArrayList<>();
for (Sexo sexo : Sexo.values()) {
list.add(new SelectItem(sexo, sexo.getAbreviatura()));
}
return list;
}
public List<Municipio> getMunicipios() {
if (municipios == null) {
municipios = municipioDAO.findAll();
}
return municipios;
}
public String newSave() {
participante = new Participante();
return "/paginas/participante_guardar?faces-redirect=true";
}
public void save(ActionEvent event) {
participanteDAO.save(participante);
participante = new Participante();
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Dados guardados com sucesso!"));
}
public String startEdit() {
return "/paginas/participante_editar?faces-redirect=true";
}
public void edit(ActionEvent event) {
participanteDAO.update(participante);
participantes = null;
try {
FacesContext.getCurrentInstance().getExternalContext().redirect("participante_listar.jsf");
} catch (IOException ex) {
Logger.getLogger(ParticipanteMBean.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String delete() {
participanteDAO.delete(participante);
participantes = null;
return "/paginas/participante_listar?faces-redirect=true";
}
public List<Participante> getListaParticipantes() {
if (participantes == null) {
participantes = participanteDAO.findAll();
}
return participantes;
}
}
Prática
Partindo do exemplo apresentado, criar os CDI Managed Beans para as outras classes simples, implementando os métodos para a interação com o Model, bem como as regras de navegação entre as páginas.