What do you think about a litle of Convention over Configuration for the JSF programming? if you like the idea, than read this ...
Posted by urubatan on December 14, 2006 at 2:15 PM EST
<Versão em portugues aqui>I think JSF ia a great technology for web development, and it gets better if you mix it with the SPring Framework, but I also think it has the same problem that Java EE 1.4 has, you have to configure every thing before you can do any think ...
and it is a lot of configuration.
I do not think that configuration is a bad thing, I think that you must be able to configure, but I do not think you must be obligated to configure any thing ...
the Spring-Annotation has a JSF module, and in this module we have some goodies that I think makes Easy to program using JSF ...
Bellow we have a little example of an users and projects application (very simple) just to illustrate what I`m talking about ...
Just to make it clear, there is no faces-config.xml, the web.xml has only 21 lines, Spring Framework and XML Schema declaration already included in that, what left us 3 lines less ..., the applicationContext.xml has exactly 6 lines, but 5 of them are schema declarations and <bean> </bean>
, after that we have only one line added to the basic applicationContext.xml, 1 servlet, 1 servlet-mapping, 1 listener e 1 context-param at web.xml and it is it,
after that you just think about coding your application ...
And how is it possible?
For doing that I had to accept that every JSP for each managed bean will be in a directory with the same name as the Managed bean, and that the Managed Beans will be configured using the Spring-Annotation annotations.
for example, if you have a bean annotated with @Bean(name="projectM")
all the JSPs for that managed bean will be placed at a directory named "projectM".
so, lets see some coding ...
this is the "memory persistence engine" I have wrote for this example, all the entities are persisted in memory using a HashMap :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); } }
after that I have created two value objects (that litle classes with lots of gets and sets and no logic at all) the User VO:
package br.com.urubatan.blog; import org.hibernate.validator.NotNull; import org.hibernate.validator.Length; 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; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("User"); sb.append("{userName='").append(userName).append('\''); sb.append(", password='").append(password).append('\''); sb.append(", fullName='").append(fullName).append('\''); sb.append('}'); return sb.toString(); } }
and the Project VO:
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; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Project"); sb.append("{name='").append(name).append('\''); sb.append(", description='").append(description).append('\''); sb.append(", users=").append(users); sb.append('}'); return sb.toString(); } }
After that litle play with Java, I started all the XML coding I need for this project:
here is my 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>
and here is my applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <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/> </beans>
all done, no mor XML for today :D
after this we can start writing all the managed beans:
look ar the UserMBean bellow
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 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); } }
the addUser method adds the selected user to the project beeing edited now, the other methods are just simple CRUD methods ...
and the ProjectMBean
in this one, I had to add some of the JSF API since in the current version of the Spring-Annotation project you can have only one @DataModel per managed bean, and I had no other way to get what was the selected user to be removed from the current project ...
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"Related Topics >>
Blog Links >>
- Login or register to post comments
- Printer-friendly version
- urubatan's blog
- 489 reads





