Blog do Urubatan
msgbartop
Desenvolvedor, Arquiteto, Palestrante, Coordenador do RSJUG, Patinador e Blogger
msgbarbottom

14 Dec 06 O que vocês acham de um pouco de Convenções para programação em JSF? se gostam da ideia leiam o POST :D

Bom, eu acho JSF um excelente framework para desenvolvimento WEB, ainda mais combinado com o Spring Framework, mas acho que tem o mesmo problema do Java EE 1.4, ou seja, exige configurações demais para ser utilizado …

bom, junto com o projeto Spring-Annotation existe um modulo para JSF, e neste modulo alguns facilitadores …

Segue um pequeno exemplo de uma aplicação de cadastro de Projetos e Usuários (bem simples) só para mostrar do que eu estou falando …
Para terem uma idéia do que foi facilitado, nesta aplicação não existe um faces-config.xml, o web.xml tem exatas 21 linhas, contando ja com a configuração do Spring Framework e declarações do XML Schema, o que ja consome 3 linhas …, e o applicationContext.xml tem exatas 6 linhas, sendo que 5 são declaração de schemas e <bean> </bean>
ou seja, é 1 linha adicionada no applicationContext.xml, 1 servlet, 1 servlet-mapping, 1 listener e 1 context-param no web.xml e era isto de configuração, só isto, o resto é só codificar a aplicação …

Mas como isto é possivel?

Simplesmente foi preciso aceitar que as JSPs de cada cadastro ficariam dentro de um diretório de mesmo nome do managed bean, e que os beans seriam configurados pelo Spring-Annotation …
e também foram usadas algumas anotações e um pouquinho de AOP no projeto Spring-Annotation …

vamos ao código então …

Esta é a minha engine de persistencia em memória para o exemplo que usa dois Maps como Backend :D

package br.com.urubatan.blog;

import net.java.dev.springannotation.annotation.Bean;

import java.util.List;
import java.util.HashMap;
import java.util.ArrayList;

/**
 * Created by IntelliJ IDEA.
 * User: Rodrigo
 * Date: 14/12/2006
 * Time: 12:00:45
 * To change this template use File | Settings | File Templates.
 */
@Bean(name = "persistence")
public class PersistenceExample {
    private HashMap<String,Project> projects = new HashMap<String,Project>();
    private HashMap<String,User> users = new HashMap<String,User>();

    public List<Project> allProjects() {
        return new ArrayList<Project>(projects.values());
    }

    public void updateRef(Project project) {
        projects.put(project.getName(), project);
    }

    public void add(Project project) {
        projects.put(project.getName(), project);
    }

    public List<User> allUsers() {
        return new ArrayList<User>(users.values());
    }

    public void updateRef(User user) {
        users.put(user.getUserName(), user);
    }

    public void add(User user) {
        users.put(user.getUserName(), user);
    }
}

Depois disto feito, escrevi dois VOs (aquelas classes que muita gente não gosta cheias de get e set … )
Projeto

package br.com.urubatan.blog;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.io.Serializable;

public class Project implements Serializable {
    private String name;
    private String description;
    private List<User> users = new ArrayList<User>();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<User> getUsers() {
        return Collections.unmodifiableList(users);
    }

    public void addUser(User u) {
        if (!users.contains(u)) {
            users.add(u);
        }
    }

    public void removeUser(User u) {
        users.remove(u);
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Project project = (Project) o;

        if (description != null ? !description.equals(project.description) : project.description != null) {
            return false;
        }
        if (name != null ? !name.equals(project.name) : project.name != null) {
            return false;
        }
        if (users != null ? !users.equals(project.users) : project.users != null) {
            return false;
        }

        return true;
    }

    public int hashCode() {
        int result;
        result = (name != null ? name.hashCode() : 0);
        result = 31 * result + (description != null ? description.hashCode() : 0);
        result = 31 * result + (users != null ? users.hashCode() : 0);
        return result;
    }

}

e Usuário

package br.com.urubatan.blog;

import java.io.Serializable;

public class User implements Serializable {
    private String userName;
    private String password;
    private String fullName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        User user = (User) o;

        if (fullName != null ? !fullName.equals(user.fullName) : user.fullName != null) {
            return false;
        }
        if (password != null ? !password.equals(user.password) : user.password != null) {
            return false;
        }
        if (userName != null ? !userName.equals(user.userName) : user.userName != null) {
            return false;
        }

        return true;
    }

    public int hashCode() {
        int result;
        result = (userName != null ? userName.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        result = 31 * result + (fullName != null ? fullName.hashCode() : 0);
        return result;
    }

}

depois disto parti para escrever os XMLs, segue o web.xml

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>Example JSF Application</display-name>
	<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
	</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>
</web-app>

e o meu applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sa="https://spring-annotation.dev.java.net/context">
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       https://spring-annotation.dev.java.net/context https://spring-annotation.dev.java.net/nonav/context.xsd"	default-autowire="byName">
	<sa:annotation-autoload>
</sa:annotation-autoload>
</beans>

Percebam que a unica configuração real do web.xml é a tag do spring-annotation que habilita o carregamento dos beans que estão anotados com @Bean

depois disto, comecei a escrever os dois managed beans, o de Usuário:

package br.com.urubatan.blog;

import java.util.List;

import net.java.dev.springannotation.annotation.*;

import javax.faces.event.ActionEvent;

@Bean(name = "userM", scope = Scope.REQUEST)
@ManagedBean
public class UserMBean {
    @Out
    @Value("#{user}")
    @DataModelSelection
    private User user;
    @Out
    @Value("#{userList}")
    @DataModel(name = "users", factory = "#{userM.list}", scope = Scope.REQUEST)
    private List<User> userList;
    private PersistenceExample persistence;
    @Value("#{project}")
    private Project project;

    public void setProject(Project project) {
        this.project = project;
    }

    public void setPersistence(PersistenceExample persistence) {
        this.persistence = persistence;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    public String list() {
        userList = persistence.allUsers();
        return "def:list";
    }

    public String create() {
        user = new User();
        return "def:form";
    }

    public String edit() {
        return "def:form";
    }

    public String update() {
        persistence.updateRef(user);
        return list();
    }

    public String save() {
        persistence.add(user);
        return list();
    }

    public void addUser(ActionEvent evt) {
        project.addUser(user);
    }
}

o metodo addUser adiciona o usuário selecionado no projeto sendo editado, os outros metodos são um CRUD padrão :D
e o ManagedBean de projetos, neste tive que mexer um pouquinho com a API do JSF no metodo removeUser, pois por enquanto o Spring-Annotation só suporta um DataModel por ManagedBean, então não era possivel utilizar @DataModel e @DataModelSelection para saber qual era o usuário selecionado dentro do projeto …

package br.com.urubatan.blog;

import java.util.List;
import java.util.ArrayList;

import net.java.dev.springannotation.annotation.*;

import javax.faces.event.ActionEvent;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.model.SelectItem;

@Bean(name = "projectM", scope = Scope.REQUEST)
@ManagedBean
public class ProjectMBean {
    @Out
    @Value("#{project}")
    @DataModelSelection
    private Project project;
    @Out
    @Value("#{projectList}")
    @DataModel(name = "projects", factory = "#{projectM.list}",scope = Scope.REQUEST)
    private List
<Project> projectList;
    private PersistenceExample persistence;
    private HtmlDataTable dataTable;
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public HtmlDataTable getDataTable() {
        return dataTable;
    }

    public void setDataTable(HtmlDataTable dataTable) {
        this.dataTable = dataTable;
    }

    public void setPersistence(PersistenceExample persistence) {
        this.persistence = persistence;
    }

    public Project getProject() {
        return project;
    }

    public void setProject(Project project) {
        this.project = project;
    }

    public List
<Project> getProjectList() {
        return projectList;
    }

    public void setProjectList(List
<Project> projectList) {
        this.projectList = projectList;
    }

    public List<SelectItem> getUsers() {
        List<SelectItem> result = new ArrayList<SelectItem>();
        for(User u : persistence.allUsers()){
            result.add(new SelectItem(u,u.getUserName(),u.getPassword()));
        }
        return result;
    }

    public String list() {
        projectList = persistence.allProjects();
        return "def:list";
    }

    public String create() {
        project = new Project();
        return "def:form";
    }

    public String edit() {
        return "def:form";
    }

    public String update() {
        persistence.updateRef(project);
        return list();
    }

    public String save() {
        persistence.add(project);
        return list();
    }

    public void removeUser(ActionEvent evt) {
        User u = (User) dataTable.getRowData();
        project.removeUser(u);
    }
}

pronto, este é todo o código necessário, algumas explicações sobre as anotações do Spring-Annotation:
a anotação @ManagedBean marca um managedBean
as anotações
@DataModel, @DataModelSelection, @DataModelIndex, @Value e @Out só funcionam dentro de um managed bean anotado com @ManagedBean

a anotação @Value é parecida com uma @Property, mas recebe como valor uma expressão da EL do JSF.
acho que é mais ou menos isto …

fora isto tem as JSPs também, estas são JSF padrão, segue o código das 5 (uma de indice, mais um list e um form para cada mbean)
Indice (home.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<f:view>
    <h:form>
        <h:panelgrid columns="1">
            <h:outputlink value="#{facesContext.externalContext.request.contextPath}/userM/list.jsf">
                <h:outputtext value="User List">
            </h:outputtext>
            <h:outputlink value="#{facesContext.externalContext.request.contextPath}/projectM/list.jsf">
                <h:outputtext value="Project List">
            </h:outputtext>
        </h:outputlink>
    </h:outputlink>
</h:panelgrid>

</h:form></f:view>

o formulário de usuários:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<f:view>
    <h:form>
        <h:panelgrid columns="3">
            <h:outputlabel for="userName" value="User Name:">
            <h:inputtext id="userName" value="#{user.userName}" disabled="#{not empty user.userName}">
            <h:message for="userName">
            <h:outputlabel for="fullName" value="Full Name:">
            <h:inputtext id="fullName" value="#{user.fullName}">
            <h:message for="fullName">
            <h:outputlabel for="password" value="Password:">
            <h:inputsecret id="password" value="#{user.password}">
            <h:message for="password">
        </h:message>
        <h:panelgrid columns="3">
            <h:commandbutton value="List" action="#{userM.list}">
            <h:commandbutton value="Projects" action="#{projectM.list}">
            <h:commandbutton value="Save" action="#{userM.save}">
        </h:panelgrid>
	</h:form>
</f:view>

A listagem de usuários:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>


    <h:form>
        <h:datatable value="#{users}" var="u">
            <f:facet name="header">
                <h:outputtext value="Users">
            </h:outputtext>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="User Name">
                </h:outputtext>
                <h:outputtext value="#{u.userName}">
            </h:outputtext>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Full Name">
                </h:outputtext>
                <h:outputtext value="#{u.fullName}">
            </h:outputtext>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Actions">
                </h:outputtext>
                <h:commandbutton value="Edit" action="#{userM.edit}">
            </h:commandbutton>
        </f:facet>
        <h:panelgrid columns="3">
            <h:commandbutton value="Projects" action="#{projectM.list}">
            <h:commandbutton value="Users" action="#{userM.list}">
            <h:commandbutton value="New User" action="#{userM.create}">
        </h:commandbutton>
    </h:form>
</f:view>

A listagem de projetos:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<f:view>
    <h:form>
        <h:datatable value="#{projects}" var="p">
            <f:facet name="header">
                <h:outputtext value="Projects"/>
            </f:facet>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Name">
                </f:facet>
                <h:outputtext value="#{p.name}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Description">
                </f:facet>
                <h:outputtext value="#{p.description}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Actions">
                </f:facet>
                <h:commandbutton value="Edit" action="#{projectM.edit}">
            </h:column>
		</h:datatable>
        <h:panelgrid columns="3">
            <h:commandbutton value="Projects" action="#{projectM.list}">
            <h:commandbutton value="Users" action="#{userM.list}">
            <h:commandbutton value="New Project" action="#{projectM.create}">
        </h:panelgrid>
	</h:form>

</f:view>

e o formulário de projetos, que ficou um pouco mais complexo que as outras JSPs por causa das duas tabelas de usuários (disponiveis e adicionados ao projeto)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>

<f:view>
    <h:form>
        <h:messages>
        <h:panelgrid columns="3">
            <h:outputlabel for="name" value="Name:">
            <h:inputtext id="name" value="#{project.name}" disabled="#{not empty project.name}">
            <h:message for="name">
            <h:outputlabel for="description" value="Description:">
            <h:inputtextarea rows="5" cols="20" id="description" value="#{project.description}">
            <h:message for="description">
        </h:panelgrid>
        <h:panelgrid columns="2">
        <h:datatable value="#{project.users}" var="u" width="100%" binding="#{projectM.dataTable}">
            <f:facet name="header">
                <h:outputtext value="Users In Project">
            </f:facet>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="User Name">
                </f:facet>
                <h:outputtext value="#{u.userName}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Full Name">
                </f:facet>
                <h:outputtext value="#{u.fullName}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Actions">
                </f:facet>
                <h:commandbutton value="Remove" actionlistener="#{projectM.removeUser}">
            </h:column>
        </h:datatable>
        <h:datatable value="#{users}" var="u" width="100%">
            <f:facet name="header">
                <h:outputtext value="Users Available">
            </f:facet>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="User Name">
                </f:facet>
                <h:outputtext value="#{u.userName}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Full Name">
                </f:facet>
                <h:outputtext value="#{u.fullName}">
            </h:column>
            <h:column>
                <f:facet name="header">
                    <h:outputtext value="Actions">
                </f:facet>
                <h:commandbutton value="Add to Project" actionlistener="#{userM.addUser}">
            </h:column>
        </h:datatable>
		</h:panelgrid>
        <h:panelgrid columns="3">
            <h:commandbutton value="List" action="#{projectM.list}">
            <h:commandbutton value="Users" action="#{userM.list}">
            <h:commandbutton value="Save" action="#{projectM.save}">
        </h:panelgrid>
    </h:form></f:view>

o modulo para JSF do spring-annotation ainda tem alguns recursos a mais, como por exemplo suporte a validação de formulários utilizando as anotações do hibernate-validator, para habilitar isto basta anotar o metodo de ação que precisa de validação com @IfInvalid, passando a pagina de erros como parametro opcional, os erros de validação detectados serão colocados como message para os campos onde ocorreu o erro, e só serão considerados os erros dos campos existentes na tela …

por exemplo o VO de usuário poderia ser alterado da seguinte maneira:

package br.com.urubatan.blog;

import org.hibernate.validator.NotNull;
import org.hibernate.validator.Length;

import java.io.Serializable;

public class User implements Serializable {
    @NotNull
    @Length(min = 3)
    private String userName;
    private String password;
    private String fullName;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        User user = (User) o;

        if (fullName != null ? !fullName.equals(user.fullName) : user.fullName != null) {
            return false;
        }
        if (password != null ? !password.equals(user.password) : user.password != null) {
            return false;
        }
        if (userName != null ? !userName.equals(user.userName) : user.userName != null) {
            return false;
        }

        return true;
    }

    public int hashCode() {
        int result;
        result = (userName != null ? userName.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        result = 31 * result + (fullName != null ? fullName.hashCode() : 0);
        return result;
    }

}

e o respectivo managed bean da seguinte forma:

package br.com.urubatan.blog;

import java.util.List;

import net.java.dev.springannotation.annotation.*;

import javax.faces.event.ActionEvent;

import org.hibernate.validator.Valid;

@Bean(name = "userM", scope = Scope.REQUEST)
@ManagedBean
public class UserMBean {
    @Out
    @Value("#{user}")
    @DataModelSelection
    @Valid
    private User user;
    @Out
    @Value("#{userList}")
    @DataModel(name = "users", factory = "#{userM.list}", scope = Scope.REQUEST)
    private List<User> userList;
    private PersistenceExample persistence;
    @Value("#{project}")
    private Project project;

    public void setProject(Project project) {
        this.project = project;
    }

    public void setPersistence(PersistenceExample persistence) {
        this.persistence = persistence;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    public String list() {
        userList = persistence.allUsers();
        return "def:list";
    }

    public String create() {
        user = new User();
        return "def:form";
    }

    public String edit() {
        return "def:form";
    }

    public String update() {
        persistence.updateRef(user);
        return list();
    }
    @IfInvalid
    public String save() {
        persistence.add(user);
        return list();
    }

    public void addUser(ActionEvent evt) {
        project.addUser(user);
    }
}


ou seja, anotar as validações necessárias no VO, colocar um @Valid no MBean por que o MBean é que vai ser validado, e esta anotação informa que aquela propriedade tem que ser validada em cascata, e um @IfInvalid na action save, agora não é mais possivel salvar um usuário que não tenha username, ou que o username seja menor que 3 caracteres …

Alguem gostou da abordagem? alguem não gostou? algum comentário? o que pode ser melhorado para a proxima versão?
espero comentários :D
Qualquer duvida de quem quiser usar isto (ja esta disponivel no Spring-Annotation 1.0.2), e quem quiser baixar o exemplo para testar em casa é só clicar aqui.

Se você gostou deste post, lembre-se de assinar o RSS feed do blog, para ser notificado de novos posts!

Tags: , ,

Reader's Comments

  1. |

    Sobre o post “O que vocês acham de um pouco de Convenções para programação em JSF?” teria como publicar a parte de persistencia com hibernate-annotations e comentar os códigos com explicações ??

    Valew, parabéns.

    Reply to this comment
  2. |

    na verdade não coloquei neste post por que iria poluir mais do que ajudar, ja que o post era sobre JSF …

    e qual exatamente a duvida que ficou? a unica coisa diferente de uma aplicação JSF padrão aqui são as anotações que estão comentadas, e a parte de navegação que também tem algumas expligações …

    acha que precisa explicar melhor esta parte?

    Reply to this comment
  3. |

    Verdade, iria poluir o post, mas se vc puder, faça um “Parte II” com a parte de persistencia com hibernate-annotations.

    Em relação à explicação, ela está boa, mas para melhor entendimento de quem está leigo, como eu, no assunto vc poderia colocar comentário no códiggo, por exemplo:

    //Estas funções fazem cachorro quente com batata e refrigerenate……
    public String list() {
    userList = persistence.allUsers();
    return “def:list”;
    }

    public String create() {
    user = new User();
    return “def:form”;
    }

    public String edit() {
    return “def:form”;
    }

    Reply to this comment
  4. |

    gostei da ideia, vou fazer uma parte II alterando o exemplo para incluir a parte de persistencia com hibernate :D

    Reply to this comment
  5. |

    Ola, muito bom o exemplo, porem o que vc colocou na lib da sua aplicação ? quais jar´s ?

    Reply to this comment
  6. |

    Marcelo Vicari:
    coloquei os jars do Spring-Annotation , Spring 2.0 e JSF apenas …
    Tem o link para download do exemplo no final do artigo, baixa ele e qualquer duvida é só perguntar :D
    Marcelo:
    não coloco comentários nos códigos de exemplo de proposito, pois fica poluido demais …

    e realmente achei que estes metodos de 2/3 linhas de código n”ao precisavam de explicação, mas se tu puder me dizer onde ficou a duvida tento melhorar no proximo :D

    Reply to this comment
  7. |

    Urubatan, e quanto a navegação do jsf? quem gerencia o jsf ou o spring-annotation? não vi nada sobre…

    [s]
    George

    Reply to this comment
  8. |

    é o que aquele “def:qualquer coisa” faz …
    quando o MBean retorna “def:qualquer coisa” a página que sera renderizada é /nomeDoMBean/qualquer coisa.jsp

    se a string retornada pela action do mbean não tiver o prefixo def: ai segue o fluxo de decisão normal, utilizando o faces-config.xml

    Reply to this comment
  9. |

    Então vc nomeia tem as paginas como list ou form? é isso?

    tks

    Reply to this comment
  10. |

    Não Entendi o /nomeDoBean pq tem q ser isso, não pode ser a minha pasta que eu desejar?

    tks

    Reply to this comment
  11. |

    exatamente, nomeio as páginas como list ou form ou coisas do tipo …

    para usar o def: é /nomeDoBean, é este o padrão do framework.
    assim as JSPs para cada mbean ficam em um diretório separado.

    se tu não quiser usar isto, é só continuar configurando a navegação no faces-config.xml :D
    se tu aceitar este padrão, tu pode utilizar configuration by exception, se tu não aceitar ele, toda a tua aplicação cai dentro do “exception”.

    Reply to this comment
  12. |

    então /nomeDoBean será a pasta para a página certo?

    tks

    Reply to this comment
  13. |

    Urubatan, vc chegou a fazer uma parte II deste tutorial, alterando o exemplo para incluir a parte de persistencia com hibernate ??

    Obrigado.

    Reply to this comment
  14. |

    George, exatamente, /nomeDoBean é a pasta onde devem estar as páginas …

    Marcelo, ainda não fiz a parte 2 não :( pouco tempo para escrever …

    vou ver se consigo fazer para a semana que vem :D

    Reply to this comment
  15. |

    Urubatan, estou montando um crud pra gerenciamento de papeis e privilégios, vou precisar de alguns help´s seus, ok?

    afinal não conheço as annotation que posso utilizar na app.

    tks ;)

    Reply to this comment
  16. |

    Urubatan o que o @DataModelSelection faz por baixo???

    Reply to this comment
  17. |

    ele é uma flag que diz para o DataModelListener criado pelo @DataModel onde colocar o valor da linha :D
    na versão atual, só é possivel utilizar um conjunto @DataModel/@DataModelSelection por managed bean, para as proximas versões, pretendo fazer com que seja possivel utilizar mais de um por mbean :D

    Reply to this comment
  18. |

    [...] Faz tempo que quando eu trabalho com JSF e Spring eu uso um VariableResolver para que todos os meus Managed Beans sejam configurados diretamente pelo Spring, agora parece ue tem mais gente descobrindo o caminho das pedras [...]

    Reply to this comment
  19. |

    Já trabalhei com o Seam e as anotações realmente fazem muita diferenca… já tem uma versao fechada do spring-annotations?

    Reply to this comment

Leave a Comment