Message Board end to end scenario
Author: Jan Horvath
Last update: 10/03/2005
Introduction:
This application provides simple message board. User (or admin) can create one or more massage lists. It uses security, so creating of new lists can be allowed only for selected users and roles.
Message and Message List is represented by CMP Entity Beans. Facade for managing this entity beans is provided by session bean.
Web part of application uses Struts Library.
Table of Contents
J2EE application
Message Board consists of three projects: J2EE application which contains EJB module and Web module.
- Go to File - new Project - Enterprise Application
- Specify MessageBoard as Name
CMP Beans
Message Entity Bean
- Select EJB module and create new Entity Bean - Message, choose CMP persistance and primary key class java.lang.Integer.
- create CMP fields (open contextual menu of bean in Project Tab and invoke Add CMP Field...)
java.lang.String subject
java.lang.String text
java.lang.String owner
java.util.Date date
- create find method findByList() with query SELECT OBJECT(o) FROM Message o WHERE o.list.key = ?1 ORDER BY o.key DESC
- create select method ejbSelectMaxId with query "SELECT MAX(o.key) FROM Message o" and return type java.lang.Integer
- create method should look like this:
(delete body of created method and Right-click on methods name and invoke Refactor->Change Method Parameters...)
public java.lang.Integer ejbCreate(String text, String subject, ListLocal list) throws javax.ejb.CreateException {
int id=0;
try {
Integer maxId=ejbSelectMaxId();
if (maxId!=null) id=maxId.intValue()+1;
} catch (javax.ejb.FinderException e) {
throw new javax.ejb.CreateException();
}
setKey(new Integer(id));
setText(text);
setSubject(subject);
setOwner(context.getCallerPrincipal().getName());
setDate(Calendar.getInstance().getTime());
return null;
}
public void ejbPostCreate(java.lang.String key, String subject, ListLocal list) {
// TODO populate relationships here if appropriate
setList(list);
}
List Entity Bean
public java.lang.Integer ejbCreate(String name, String description, String roles) throws javax.ejb.CreateException {
if (name == null) {
throw new javax.ejb.CreateException("The field \"name\" must not be null");
}
// TODO add additional validation code, throw CreateException if data is not valid
int id=0;
try {
Integer maxId=ejbSelectMaxId();
if (maxId!=null) id=maxId.intValue()+1;
} catch (javax.ejb.FinderException e) {
throw new javax.ejb.CreateException();
}
setKey(new Integer(id));
setName(name);
setDescription(description);
setOwner(context.getCallerPrincipal().getName());
setRoles(roles);
return null;
}
Add find method findAll() with query SELECT OBJECT(o) FROM List o
Add Home method getAllListNames()
public Collection ejbHomeGetAllListNames() {
Collection names=null;
try {
names=ejbSelectAll();
} catch(javax.ejb.FinderException e) {
throw new RuntimeException(e.getMessage());
}
return names;
}
Open ejb-jar.xml config file, select CMP Relationships tab and Add New Relationship:
| Entity bean: | Message | List |
| Multiplicity: | Many | One |
| CMR field | list | CMR field: messages |
| Add To Local Interface: | getter | getter |
| Add To Local Interface: | setter | |
Board Session Bean
- Add lookup methods for Message and List entity beans by Contextual menu - Enterprise Resources->Call Enterprise Bean
- Add this private field to bean class:
private ListLocalHome llh = null;
private MessageLocalHome mlh = null;
- Modify create method of Board bean:
public void ejbCreate() {
// TODO implement ejbCreate if necessary, acquire resources
// This method has access to the JNDI context so resource aquisition
// spanning all methods can be performed here such as home interfaces
// and data sources.
llh = lookupListBean();
mlh = lookupMessageBean();
}
- Add this business methods:
public Collection getListNames() {
return llh.getAllListNames();
}
public Collection getMessagesInList(Integer id) {
ArrayList al = null;
try {
Iterator it = mlh.findByList(id).iterator();
al = new ArrayList();
while (it.hasNext()) {
MessageLocal ml = (MessageLocal) it.next();
al.add(new MessageDTO((Integer) ml.getPrimaryKey(),
ml.getText(),
ml.getSubject(),
ml.getOwner(),
ml.getDate()));
}
} catch (FinderException e) {
throw new RuntimeException(e.getMessage());
}
return al;
}
public Collection getLists() {
ArrayList al = null;
try {
Iterator it = llh.findAll().iterator();
al = new ArrayList();
while (it.hasNext()) {
ListLocal ll = (ListLocal) it.next();
al.add(new ListDTO((Integer) ll.getPrimaryKey(),
ll.getDescription(),
ll.getName(),
ll.getOwner(),
ll.getRoles()));
}
} catch (FinderException e) {
throw new RuntimeException(e.getMessage());
}
return al;
}
public void addMessage(Integer listId, String subject, String text) {
try {
messageboard.MessageLocal ml=mlh.create(text, subject,
llh.findByPrimaryKey(listId));
} catch(javax.ejb.FinderException e) {
throw new RuntimeException(e.getMessage());
} catch (CreateException e) {
throw new RuntimeException(e.getMessage());
}
}
public Integer createList(java.lang.String name, String description) {
try {
messageboard.ListLocal ll=llh.create(name, description, "users");
return (Integer)ll.getPrimaryKey();
} catch (CreateException e) {
throw new RuntimeException(e.getMessage());
}
}
Web Project
- Create New Web Project, in create wizard choose Struts Framework.
- Create new CachingServiceLocator
- Create new StrutsAction, choose name ListsAction and ActionPath /listsaction
- Add reference to Board session bean - by Contextual menu - Enterprise Resources->Call Enterprise Bean
- Add this code to body of execute method:
messageboard.BoardRemote br=lookupBoardBean();
HttpSession session = request.getSession();
session.setAttribute("lists",br.getLists());
session.removeAttribute("listId");
return mapping.findForward(SUCCESS);
- Add reference to Board session bean
- Add this to execute method:
HttpSession session = request.getSession();
Integer listId=(Integer) session.getAttribute("listId");
try {
listId=new Integer(Integer.parseInt(request.getParameter("id")));
session.setAttribute("listId", listId);
} catch (NumberFormatException e) {
}
if (listId==null) return mapping.findForward(LISTS);
messageboard.BoardRemote br=lookupBoardBean();
DynaActionForm daf = (DynaActionForm)form;
String text=daf.getString("text");
String subject=daf.getString("subject");
if ((text.trim().length()>0) && (subject.trim().length()>0)) {
br.addMessage(listId, subject, text);
form.reset(mapping, request);
}
session.setAttribute("messages",br.getMessagesInList(listId));
return mapping.findForward(SUCCESS);
- Create new Struts Action named NewListAction
- Add reference to Board session bean
- Add this to exeecute method:
DynaActionForm daf = (DynaActionForm)form;
String description=daf.getString("description");
String name=daf.getString("name");
if (name.trim().length()==0) return mapping.findForward(FORM);
messageboard.BoardRemote board=lookupBoardBean();
board.createList(name, description);
return mapping.findForward(SUCCESS);
- Open struts-config.xml file
- Add FormBeans definitions:
newListForm with fields String name, String description
messageForm with fields String subject, String description
for adding Form Beans use contextual menu in editor->Add FormBean

and for adding Form Bean properties use contextual menu in editor->Add FormBean Property

- Create new Struts Actions defined by the following table. For creating new actions use New Struts Action wizard.
| Input Resource |
Form Name |
Action Path |
Package |
Class Name |
| newlist.jsp |
newListForm |
/newlist |
messageboard.web |
NewListAction |
| lists.jsp |
|
/lists |
ListsAction |
| list.jsp |
messageForm |
/list |
ListAction |
| |
|
/logout |
LogoutAction |

- Add forwards to Struts Actions using Struts->Add Forward wizard in struts-config.xml editor.
| Action |
Forward Name |
Forward Path |
Redirect |
| NewListAction |
success |
/lists.do |
false |
| form |
/newlist.jsp |
false |
| ListsAction |
success |
/lists.jsp |
false |
| ListAction |
success |
/list.jsp |
false |
| lists |
/lists.do |
true |
| LogoutAction |
success |
/lists.do |
true |

Deploy and Run Project
- Now you can deploy application and test how it works:
You can download project sources here