Back-End

6 mar, 2013

O que ganho usando Jboss Seam?

Publicidade

Texto direcionado a usuários do JSF 1.2 tratando do uso do Jboss Seam 2.x.

Para quem não conhece, o Seam é um framework destinado ao desenvolvimento web criado pelo mesmo criador do Hibernate, Gavin King, e que tem como um de seus principais objetivos facilitar a integração entre JSF e EJB3.Muitos são os ganhos obtidos pelo uso do Seam, dentre estes irei me ater aos seguintes:

  1. Menos XMLs;
  2. Requisições por GET;
  3. Facilidade na utilização de ComboBox;
  4. Injeção de Dependências via anotações;
  5. Facilidade no envio de e-mails;
  6. Agendamento de tarefas;
  7. URL user friendly;
  8. Suporte a transações;
  9. Integração com Groovy, Hibernate, Spring, entre outros.
Para não estender muito, neste artigo irei falar dos três primeiros. Falarei dos demais em artigos futuros.

1. Menos XMLs

O Seam diminui a utilização de XML em vários aspectos, como por exemplo:

1.1. Navegação

Usando apenas o JSF 1.2, a navegação entre páginas deve ser definida via XML, no arquivo faces-config.xml, e usada por meio de um método no Managed Bean que retorne um String de saída configurada no faces-config.xml. Conforme o exemplo abaixo:

faces-config.xml:

<navegation-rule>
  <from-view-id>/person/people.xhtml</from-view-id>
  <navegation-case>
    <from-outcome>edit</from-outcome>
    <to-view-id>/person/edit.xhtml</to-view-id>
  </navegation-case>
</navegation-rule>

Managed Bean:

public String editPeople() {
  return "edit";
}

Com o Seam, isso pode ser feito de forma mais simples, apenas retornando o nome da página no método do Managed Bean:

public String editPeople() {
   return "/person/edit.xhtml";
}

1.2 Registro de Managed Beans

Para que cada Managed Bean seja utilizado nas views do JSF é necessário que este esteja registrado no faces-config.xml, como mostrado abaixo:

<?xml version="1.0" encoding="UTF-8"?>
  <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="htt      p://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">

  <managed-bean>
    <managed-bean-name>people</managed-bean-name>
    <managed-bean-class>br.com.People</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>

</faces-config>

Com o Seam, basta que o bean seja declarado como um componente do Seam, por meio da anotação @Name. Deste modo, o bean passar a ser gerenciado pelo Seam. Ou seja, além de ser um Managed Bean, também é um Seam Component.

@Name("people")
public class People {
  //...
}

2. Requisições por GET

O JSF 1.2 não lida bem com parâmetros GET. Não que seja impossível “capturar” tais parâmetros, mas é trabalhoso e não natural. Veja o seguinte exemplo que apresenta uma forma recuperar o parâmetro “id” passado por GET no bean:

String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"));

O Seam facilita muito esse trabalho fazendo “bind” dos parâmetros GET por meio da anotação @RequestParameter:

@RequestParameter
private Long id = null;

3. Facilidade na utilização de ComboBox

Imagine a seguinte situação: você pretende apresentar ao usuário um ComboBox com as regiões do Brasil onde cada região possui um id e um nome. Para você, é importante saber o id da região escolhida pelo usuário. Para o usuário, é importante escolher a região pelo nome, não pelo id.
Para resolver isso no JSF é necessário criar um mapa que contenha os nomes e os ids semelhante a esse:

public class MostraRegioes {

  public Map<String, Regioes> getRegioes(){
    Map<String, Regioes> regioes = new HashMap<String, Regioes>();
    for(Regioes r : Regioes.values()) {
      regioes.put(r.getNome(), 1);
    }
    return regioes;
  }

}

E usá-lo da seguinte forma:

<h:selectOneMenu>
  <f:selectItems value="#{MostraRegioes.regioes}"/>
</h:selectOneMenu>

O que não é produtivo quando temos um sistema com muitos combos. Pois teríamos que fazer um método (convertendo de lista ou Array para um mapa ou List) para cada combo. Felizmente o Seam ajuda nisso com o componente que faz binding com uma lista/array comum. Veja:

<h:selectOneMenu>
  <s:selectItems value="#{MostraRegioes.regioes}"
    var="regiao" label=#{regiao.nome}"/>
</h:selectOneMenu>