前言
在上一篇實戰(zhàn)EJB教程里,我們學寫了一個CMP的實體Bean和sessionBean,sessionBean通過模型來操作實體Bean,基于Struts的jsp Framework 在javabean中訪問EJB,得出最終結果在JSP視圖層中顯示,雖然簡單,但這也是基本的流程!在完成這篇教程之后,我就在思量如何再寫一個完整的應用,恰好論壇中的深空小妖寫了一個基于php的留言本!于是我就想到也寫一篇留言本的文章吧,留言本雖然很簡單,但它卻是一個基礎,增加管理回復等就相當于一個小型的BBS,稍做修改也可以將它變成一個文章發(fā)布系統(tǒng)!
在我考慮之下,我決定寫一個基于j2ee的留言本!
用于此次教學的就是留言本的tech版,它相當簡單,只具有留言和查看的功能!但是對初學者來說這卻是最好的入門捷徑!
廣告
在此tech版留言本的基礎上我二次開發(fā)了它的商業(yè)版(數(shù)據(jù)庫采用Oracle9i)!在完成我的tech版后,大家可以根據(jù)我下面的提示來定制自己的商業(yè)版!
1。商業(yè)版支持國際化功能,根據(jù)客戶端IE語言自動切換相對應的語言信息資源,采用UTF-8的編碼!
(利用struts的國際化功能)
2。完整的后臺管理功能,以管理員登陸留言本后,可對留言進行刪除,編輯,回復
(增加管理員權限的表,和實體BEAN)
3。LOG寫日志功能
(利用log4J)
4。數(shù)據(jù)庫轉為xml文件導入導出
(看看JDOM,會有不小的收獲)
5。上傳下載功能
(jspsmartupload.jar)
6。留言查找功能
(我的方法是再寫出一個搜索的sessionBean,當然也可以看看lUCene,一個開源的搜索引擎包)
7。個性化設置
(能完成以上的相信這個就不成問題)
本人已經(jīng)注冊了j2eestudio.com的域名,希望能與志同道合的朋友共同合作,請PM我!
PS又PS,如果有獨立服務器的朋友幫忙最好!
相關知識
本篇立足于初學者,因此對一些相關概念的東西我會提一下,更具體的當然希望你在完成本教程后去Google上搜一下,這樣印像更深刻!
J2EE:適用于創(chuàng)建服務器應用程序和服務的Java 2平臺企業(yè)版(Java 2 Platform EnterPRise Edition,J2EE)
EJB:商業(yè)組件的部署環(huán)境,在EJB Server中提供了分布式計算環(huán)境中組件需要的所有服務,例如組件生命周期的管理、數(shù)據(jù)庫連接的管理、分布式事務的支持、組件的命名服務等等。
Weblogic:BEA公司出品的J2ee平臺應用服務器,全面支持J2EE標準,從6.0版開始率先支持EJB2.0規(guī)范,內置jdk為1.3.1版,雖然目前該產品已經(jīng)出到了8.1,但我仍對小巧的6.1sp2版本情有獨鐘,基本上能滿足我學習和工作的需要,不過它的軟肋就是JDK的版本太低,雖然也可以自己將JDK的版本換成JDK1.4.X,但是或多或少會出現(xiàn)些問題,也因由此,我的struts一直使用的是1.1-b1版,因為在此后的正式版無法在weblogic6.1上運行!不得不說是遺憾!!
Struts:Struts是采用Java Servlet/JavaServer Pages技術,開發(fā)Web應用程序的開放源碼的framework。Struts是apache.org開源組織Jakarta項目的一部分,在論壇中見到有人說它最終會被淘汰,其實鼓吹這種論點的早就見到過,Struts也許的確不算是最高效的JSP framework,學起來有些困難,但當你真正掌握,你才會發(fā)現(xiàn)它的靈活與強大,也甚至有人說SUN的JSP幸虧有struts這顆救命稻草,不然早就完了一說呢,不管怎么說,Struts已經(jīng)有了相當廣泛的商業(yè)應用,而且網(wǎng)上的資料也很多,希望大家認真學學,大家可以到官方網(wǎng)站上看看
jakarta.apache.org/struts
題外話:struts1.1允許多個控制文件,不像我們原來為了寫一個控制文件經(jīng)常check in/out啦!可我選擇weblogic6.1就沒法用struts1.1郁悶呀!
JSP:這個相信不用我說了吧,它可以像asp,PHP那種寫法,將控制語句代碼夾雜在Html代碼中間,相對于比較復雜的JSP頁面,比如JIVE論壇的JSP頁面吧,你就會明白,看了就會犯暈,所以我們完全可以把控制語句交給struts來處理,這樣我們在頁面中看到的就是干凈“代碼”,更利于團體合作,發(fā)揮各人所才,程序員可以專心致志的寫代碼,而網(wǎng)頁設計師則可以設計漂亮的頁面!
相關工具
MySQL:今次學習版的數(shù)據(jù)庫就用它了。
weblogic6.1sp2:我已經(jīng)介紹N次了吧,呵呵,相關配置看看我以前的貼子。
Jbuilder7:EJB,JSP全在這里搞定啦!
Struts1.1-b1:去下載吧,不過我會提供一個經(jīng)我修改支持中文的struts.jar
Struts console:寫Struts-config.xml的好工具,真是太方便了
mysql.jar:提供連接mysql的JDBC驅動
平臺搭建請參看我以前的相關貼子,一些工具包我會試著找空間下載的,OK,今天暫到這里,明天我們進入代碼實戰(zhàn)篇!有什么問題請進論壇PM我!

/*
MySQL Backup
Source Host: localhost
Source Server Version: 4.0.12-nt
Source Database: guestbook
Date: 2003-09-14 15:09:17
*/
use guestbook ;
#----------------------------
# Table structure for book
#----------------------------
create table book (
id int(11) not null auto_increment,
name varchar(100) not null,
email varchar(50),
qq varchar(50),
posttime datetime not null default '0000-00-00 00:00:00',
`comment` text not null,
ip varchar(50) not null,
primary key (id))
type=MyISAM;
#----------------------------
# No records for table book
#----------------------------
創(chuàng)建實體Bean
和上篇實戰(zhàn)EJB一樣,我們在Jbuilder中先建立一個guestbook.jpx項目,然后再利用向導建立EJB名為book,接著我們需要建立它的數(shù)據(jù)源,也命名為book,當然你想取什么名字都行,不過以后在weblogic中的數(shù)據(jù)源配置要和這里寫的一樣,由于這些配置和上一篇相同,所以這里我都省去了,請大家仔細看上篇的貼子,有問題請PM我!
首先創(chuàng)建book表的CMP實體Bean文件,由于ID是在數(shù)據(jù)庫中自動增加,在此我們可以將它刪除,而指定name為主鍵,同時我們修改posttime的類型為java.lang.String.
接下來我們設計模型,這里放在value中,下面是BookValue.java的源代碼
package guestbook.maxuan.ejb.entity.value;
import java.io.*;
public class BookValue implements Serializable{
public java.lang.String name;
public java.lang.String email;
public java.lang.String qq;
public java.lang.String posttime;
public java.lang.String comment;
public java.lang.String ip;
public java.lang.String action;
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException,
IOException {
ois.defaultReadObject();
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public java.lang.String getPosttime() {
return posttime;
}
public void setPosttime(java.lang.String posttime) {
this.posttime = posttime;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
book.java的源代碼
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import java.util.*;
import guestbook.maxuan.ejb.entity.value.*;
public interface Book extends javax.ejb.EJBLocalObject {
public void setName(String name);
public String getName();
public void setEmail(String email);
public String getEmail();
public void setQq(String qq);
public String getQq();
public void setPosttime(String posttime);
public String getPosttime();
public void setComment(String comment);
public String getComment();
public void setIp(String ip);
public String getIp();
public BookValue getValue();
public void setValue(BookValue value);
}
BookBean.java的源代碼
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import guestbook.maxuan.ejb.entity.value.*;
abstract public class BookBean implements EntityBean {
EntityContext entityContext;
public java.lang.String ejbCreate(java.lang.String name)
throws CreateException {
setName(name);
return null;
}
public java.lang.String ejbCreate(BookValue value) throws CreateException {
setValue(value);
return null;
}
public void ejbPostCreate(java.lang.String name) throws CreateException {
/**@todo Complete this method*/
}
public void ejbPostCreate(BookValue value) throws CreateException {
}
public void ejbRemove() throws RemoveException {
/**@todo Complete this method*/
}
public abstract void setName(java.lang.String name);
public abstract void setEmail(java.lang.String email);
public abstract void setQq(java.lang.String qq);
public abstract void setPosttime(java.lang.String posttime);
public abstract void setComment(java.lang.String comment);
public abstract void setIp(java.lang.String ip);
public abstract java.lang.String getName();
public abstract java.lang.String getEmail();
public abstract java.lang.String getQq();
public abstract java.lang.String getPosttime();
public abstract java.lang.String getComment();
public abstract java.lang.String getIp();
public void ejbLoad() {
/**@todo Complete this method*/
}
public void ejbStore() {
/**@todo Complete this method*/
}
public void ejbActivate() {
/**@todo Complete this method*/
}
public void ejbPassivate() {
/**@todo Complete this method*/
}
public void unsetEntityContext() {
this.entityContext = null;
}
public void setEntityContext(EntityContext entityContext) {
this.entityContext = entityContext;
}
public BookValue getValue(){
BookValue value = new BookValue();
value.setName(getName());
value.setEmail(getEmail());
value.setQq(getQq());
value.setPosttime(getPosttime());
value.setComment(getComment());
value.setIp(getIp());
return value;
}
public void setValue(BookValue value){
setName(value.getName());
setEmail(value.getEmail());
setQq(value.getQq());
setPosttime(value.getPosttime());
setComment(value.getComment());
setIp(value.getIp());
}
}
BookHome.java的源代碼
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import java.util.*;
import guestbook.maxuan.ejb.entity.value.*;
public interface BookHome extends javax.ejb.EJBLocalHome {
public Book create(String name) throws CreateException;
public Book create(BookValue value) throws CreateException;
public Collection findAll() throws FinderException;
public Book findByPrimaryKey(String name)
throws FinderException;
}
記得要寫findall的Query語句:SELECT OBJECT(o) FROM Book AS o
接下來我們設計模型,這里放在value中,下面是BookValue.java的源代碼
<textarea columns=100 rows=50>
package guestbook.maxuan.ejb.entity.value;
import java.io.*;
public class BookValue implements Serializable{
public java.lang.String name;
public java.lang.String email;
public java.lang.String qq;
public java.lang.String posttime;
public java.lang.String comment;
public java.lang.String ip;
public java.lang.String action;
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream ois)throws ClassNotFoundException,
IOException {
ois.defaultReadObject();
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public java.lang.String getPosttime() {
return posttime;
}
public void setPosttime(java.lang.String posttime) {
this.posttime = posttime;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
</textarea>
book.java的源代碼
<textarea columns=100 rows=50>
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import java.util.*;
import guestbook.maxuan.ejb.entity.value.*;
public interface Book extends javax.ejb.EJBLocalObject {
public void setName(String name);
public String getName();
public void setEmail(String email);
public String getEmail();
public void setQq(String qq);
public String getQq();
public void setPosttime(String posttime);
public String getPosttime();
public void setComment(String comment);
public String getComment();
public void setIp(String ip);
public String getIp();
public BookValue getValue();
public void setValue(BookValue value);
}
</textarea>
BookBean.java的源代碼
<textarea columns=100 rows=50>
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import guestbook.maxuan.ejb.entity.value.*;
abstract public class BookBean implements EntityBean {
EntityContext entityContext;
public java.lang.String ejbCreate(java.lang.String name)
throws CreateException {
setName(name);
return null;
}
public java.lang.String ejbCreate(BookValue value) throws CreateException {
setValue(value);
return null;
}
public void ejbPostCreate(java.lang.String name) throws CreateException {
/**@todo Complete this method*/
}
public void ejbPostCreate(BookValue value) throws CreateException {
}
public void ejbRemove() throws RemoveException {
/**@todo Complete this method*/
}
public abstract void setName(java.lang.String name);
public abstract void setEmail(java.lang.String email);
public abstract void setQq(java.lang.String qq);
public abstract void setPosttime(java.lang.String posttime);
public abstract void setComment(java.lang.String comment);
public abstract void setIp(java.lang.String ip);
public abstract java.lang.String getName();
public abstract java.lang.String getEmail();
public abstract java.lang.String getQq();
public abstract java.lang.String getPosttime();
public abstract java.lang.String getComment();
public abstract java.lang.String getIp();
public void ejbLoad() {
/**@todo Complete this method*/
}
public void ejbStore() {
/**@todo Complete this method*/
}
public void ejbActivate() {
/**@todo Complete this method*/
}
public void ejbPassivate() {
/**@todo Complete this method*/
}
public void unsetEntityContext() {
this.entityContext = null;
}
public void setEntityContext(EntityContext entityContext) {
this.entityContext = entityContext;
}
public BookValue getValue(){
BookValue value = new BookValue();
value.setName(getName());
value.setEmail(getEmail());
value.setQq(getQq());
value.setPosttime(getPosttime());
value.setComment(getComment());
value.setIp(getIp());
return value;
}
public void setValue(BookValue value){
setName(value.getName());
setEmail(value.getEmail());
setQq(value.getQq());
setPosttime(value.getPosttime());
setComment(value.getComment());
setIp(value.getIp());
}
}</textarea>
BookHome.java的源代碼
<textarea columns=100 rows=50>
package guestbook.maxuan.ejb.entity;
import javax.ejb.*;
import java.util.*;
import guestbook.maxuan.ejb.entity.value.*;
public interface BookHome extends javax.ejb.EJBLocalHome {
public Book create(String name) throws CreateException;
public Book create(BookValue value) throws CreateException;
public Collection findAll() throws FinderException;
public Book findByPrimaryKey(String name)
throws FinderException;
}
</textarea>進入討論組討論。
記得要寫findall的Query語句:SELECT OBJECT(o) FROM Book AS o
package guestbook.maxuan.ejb.control;
import javax.ejb.*;
import java.util.*;
import java.rmi.*;
import guestbook.maxuan.ejb.entity.value.*;
public interface BookControl extends javax.ejb.EJBObject {
public void savely(BookValue value) throws RemoteException;
public ArrayList getLyList() throws RemoteException;
}
package guestbook.maxuan.ejb.control;
import javax.ejb.*;
import java.util.*;
import guestbook.maxuan.ejb.entity.*;
import guestbook.maxuan.ejb.entity.value.*;
public class BookControlBean implements SessionBean {
SessionContext sessionContext;
public void ejbCreate() throws CreateException {
/**@todo Complete this method*/
}
public void ejbRemove() {
/**@todo Complete this method*/
}
public void ejbActivate() {
/**@todo Complete this method*/
}
public void ejbPassivate() {
/**@todo Complete this method*/
}
public void setSessionContext(SessionContext sessionContext) {
this.sessionContext = sessionContext;
}
public void savely(BookValue value) {
Book book=null;
try {
javax.naming.Context context =
new javax.naming.InitialContext();
BookHome bookHome= (BookHome)context.lookup("Book");
if(value.getAction().equals("add")){
book=bookHome.create(value);
}else{
try{
book=bookHome.findByPrimaryKey(value.getName());
book.setValue(value);
}catch(FinderException fe){
}
}
}catch (Exception ex) {
throw new EJBException(ex);
}
}
public ArrayList getLyList(){
ArrayList LyList=new ArrayList();
try {
javax.naming.Context context = new
javax.naming.InitialContext();
BookHome bookHome= (BookHome)context.lookup("Book");
Collection lyCntl = bookHome.findAll();
Iterator iterator = lyCntl.iterator();
while(iterator.hasNext()){
Book book = (Book) iterator.next();
LyList.add(book.getValue());
}
}catch (Exception ex) {
throw new EJBException(ex);
}
return LyList;
}
}
BookControlHome的源代碼
package guestbook.maxuan.ejb.control;
import javax.ejb.*;
import java.util.*;
import java.rmi.*;
public interface BookControlHome extends javax.ejb.EJBHome {
public BookControl create() throws CreateException,
RemoteException;
}
這樣我們就完成了sessionBean的編寫,它操作實體Bean賦于value的值,
這里比上次的教程多了寫入的操作!進入討論組討論。
struts部份
首先,請大家下載jakarta-struts-1.1-b1.zip,直接在google里鍵入搜索即可,此版本可應用布署在weblogic6.1中。記得順便把jakarta-struts-1.1-b1-src.zip也下了,這是它的源碼文件,方便我們修改??!
打開jakarta-struts-1.1-b1.zip這個壓縮包文件,INSTALL、LICENSE、README三個文件不用說了自己看,lib文件夾中就是所需要的庫文件和標簽文件,webapps中有幾個示例文件,struts-documentation.war可裝配到weblogic中,一定要看看,詳盡的文檔!
首先,我們要在JBuilder中定義struts庫文件的位置,點擊TOOLS菜單在下拉中選中Configure Libraries,在彈出的窗口中新定義一個LIB,我們取名為struts 1.1-b1,定義到Project中,當然為了以后方便,你可以指定為User home!

這里我是把jakarta-struts-1.1-b1.zip文件夾直接解壓到應用目錄guestbook的lib中,將struts包中所有的*.jar文件選中加入,然后點OK即完成了struts 1.1-b1庫文件的定義!

然后我們需要指定在此次guestbook的項目應用中引入struts 1.1-b1,在打開guestbook.jpx后,在Project菜單中下拉選中Project Properties,在彈出的窗口中,在下面點擊Required Libraries,出現(xiàn)畫面如下圖所示:

點右邊的ADD,將剛才我們定義的struts 1.1-b1庫文件加入,如下圖

以上部分,我們完成了Struts1.1-b1在此次教程應用中的配置!
進入討論組討論。package guestbook.maxuan.action;
import javax.naming.*;
import java.util.Properties;
import java.util.*;
import javax.rmi.PortableRemoteObject;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Vector;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.MessageResources;
import guestbook.maxuan.ejb.control.*;
public class PAction extends Action{
//public ActionErrors errors = new ActionErrors();
public BookControl control = null;
public Context getInitialContext() {
String url = "t3://127.0.0.1:";
String user = null;
String passWord = null;
Properties properties = null;
ActionServlet actionServlet = this.getServlet();
String port = actionServlet.getServletConfig().
getInitParameter("port");
url = url + port;
try {
properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, url);
if (user != null) {
properties.put(Context.SECURITY_PRINCIPAL, user);
properties.put(Context.SECURITY_CREDENTIALS, password == null ? "" : password);
}
return new InitialContext(properties);
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
public BookControl getInitControl( ){
BookControl control = null;
Context ctx = getInitialContext();
try{
Object object = ctx.lookup("BookControl");
BookControlHome bookcHome =
(BookControlHome) PortableRemoteObject.narrow(object,
BookControlHome.class);
control = bookcHome.create();
}catch(Exception e){
e.printStackTrace();
}
return control;
}
}
package guestbook.maxuan.action;
import javax.naming.*;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
import java.util.*;
import java.util.Locale;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ForwardingActionForward;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.MessageResources;
import guestbook.maxuan.ejb.control.*;
public class LyListAction extends PAction{
public ActionForward perform(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
Locale locale = getLocale(request);
HttpSession session = request.getSession();
Context ctx = (Context)session.getAttribute("ctx");
if(ctx==null){
ctx = getInitialContext();
session.setAttribute("ctx",ctx);
}
try{
Object object = ctx.lookup("BookControl");
BookControlHome bookHome =
(BookControlHome) PortableRemoteObject.narrow(object,
BookControlHome.class);
BookControl bookControl = bookHome.create();
ArrayList lyList = bookControl.getLyList();
session.setAttribute("lyList",lyList);
}catch(Exception e){
e.printStackTrace();
}
return (mapping.findForward("success"));
}
}
package guestbook.maxuan.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import guestbook.maxuan.ejb.entity.value.*;
public final class LyForm extends ActionForm{
public String action="add";
public String name;
public String email;
public String qq;
public String comment;
private BookValue value = new BookValue();
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public BookValue getValue(){
value.setName(name);
value.setEmail(email);
value.setQq(qq);
value.setComment(comment);
value.setAction(action);
return value;
}
public void setValue(BookValue value){
name = value.getName();
email = value.getEmail();
qq = value.getQq();
comment = value.getComment();
action = value.getAction();
}
}
package guestbook.maxuan.action;
import javax.naming.*;
import java.util.Properties;
import java.util.*;
import javax.rmi.PortableRemoteObject;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Vector;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.MessageResources;
import guestbook.maxuan.action.PAction;
import guestbook.maxuan.ejb.entity.value.*;
import guestbook.maxuan.ejb.entity.*;
import guestbook.maxuan.ejb.control.*;
import java.util.Collection;
public class LyEditAction extends PAction{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
Locale locale = getLocale(request);
MessageResources messages = getResources(request);
HttpSession session = request.getSession();
String action = request.getParameter("action");
Context ctx = (Context)session.getAttribute("ctx");
BookValue value =(BookValue) request.getAttribute("value");
//errors.clear();
if (form == null) {
form = new LyForm();
if ("request".equals(mapping.getScope())) {
request.setAttribute(mapping.getAttribute(), form);
} else {
session.setAttribute(mapping.getAttribute(), form);
}
}
if(ctx==null){
ctx = getInitialContext();
session.setAttribute("ctx",ctx);
}
LyForm lyForm = (LyForm) form;
if(action!=null){
lyForm.setAction(action);
}
if (value!=null){
try {
PropertyUtils.copyProperties(lyForm, value);
} catch (Exception e) {
}
}
return (mapping.findForward("success"));
}
}
package guestbook.maxuan.action;
import javax.naming.*;
import java.util.Properties;
import java.util.*;
import java.text.*;
import javax.rmi.PortableRemoteObject;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Vector;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.util.MessageResources;
import guestbook.maxuan.action.PAction;
import guestbook.maxuan.ejb.entity.value.*;
import guestbook.maxuan.ejb.entity.*;
import guestbook.maxuan.ejb.control.*;
import java.sql.*;
public final class LySaveAction extends PAction{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
Locale locale = getLocale(request);
MessageResources messages = getResources(request);
HttpSession session = request.getSession();
BookValue value=null;
LyForm lyForm = (LyForm) form;
Context ctx = (Context)session.getAttribute("ctx");
//errors.clear();
if(control==null){
control=getInitControl();
session.setAttribute("control",control);
}
//errors = lyForm.check();
try {
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter=
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置留言時間格式
String datestr = formatter.format(new Timestamp(cal.getTime().getTime()));
value = lyForm.getValue();
value.setIp(request.getRemoteAddr());//寫入訪問者IP
value.setPosttime(datestr);
control.savely(value);
}catch(Exception e){
e.printStackTrace();
}
return (mapping.findForward("success"));
}
}
JSP部份
JSP在本篇教程應用中作為視圖層,在它里面,你看不到傳統(tǒng)的<% %>包含的控制語句,取而代之的是Struts的標簽控制!
首先,我們需要在guestbook.jpx的應用中建立web application應用,命名為guestbook,點開它下面的Deployment descriptors,我們會看到web.xml和weblogic.xml兩個文件,它們都是建立web application后自動產生的(當你配置的項目應用服務為weblogic時,才會生成weblogic.xml文件,具體配置請見拙作一)
現(xiàn)在我們雙擊weblogic.xml文件來編輯它,這里我們主要是能讓它支持中文!
weblogic.xml源代碼
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems,
Inc.//DTD Web Application 6.1//EN"
"http://www.bea.com/servers/wls610/dtd/weblogic-web-jar.dtd">
<weblogic-web-app>
<jsp-descriptor>
<jsp-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</jsp-param>
</jsp-descriptor>
</weblogic-web-app>
接著我們需要編輯web.xml文件,主要是配置默認的首頁文件,Servlets和Tag Libraries。你可以在WebApp DD Editor項目中配置,也可以直接在Source面板中直接編寫源代碼
web.xml源代碼
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems,
Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>port</param-name>
<param-value>7001</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
在完成以上兩個文件的編寫后,我們把struts1.1-b1中的所有控制標簽文件(除*.jar外的所有文件)拷貝到留言本的應用目錄WEB-INF目錄中(當你在JBuilder的項目應用中建立web application時,它就會自己幫你建立WEB-INF),如果你以目錄形式來發(fā)布此次應用,你必須手動在WEB-INF目錄下建立一個lib目錄,將所有需要的LIB資源文件拷進去,當然如果你在JBuilder中編譯此web application它除了會自動將WEB應用打包為guestbook.war文件外,還會自動在WEB-INF中建立LIB文件夾,并將相關的LIB資源文件拷進去!
接著我們需要建立struts-config.xml文件,它是配置struts控制的重要文件,編寫Struts-config.xml的利器非Struts Console不可,下邊是詳細的圖解:
首先我們新建一個struts config文件,我們選用Struts1.1 Config File,點OK
點擊Form Beans新建一個lyForm,NAME:lyForm,Type:guestbook.maxuan.action.LyForm







在完成后,我們再看Form Beans中的lyForm的Referencing Actions就會看到path中已經(jīng)有了/saveLy和/editLy


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//
Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="lyForm" type="guestbook.maxuan.action.LyForm" />
</form-beans>
<action-mappings>
<action path="/lyList"
type="guestbook.maxuan.action.LyListAction">
<forward name="success" path="/indexCnt.jsp" redirect="false" />
</action>
<action path="/saveLy" type="guestbook.maxuan.action.LySaveAction"
name="lyForm" input="/ly.jsp"
scope="request">
<forward name="success" path="/index.jsp" redirect="true" />
</action>
<action path="/editLy" type="guestbook.maxuan.action.LyEditAction"
name="lyForm" scope="request">
<forward name="success" path="/ly.jsp" redirect="false" />
</action>
</action-mappings>
<message-resources parameter="ApplicationResources"
key="org.apache.struts.action.MESSAGE" />
</struts-config>
<%@ taglib uri='/WEB-INF/struts-template.tld' prefix='template' %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>留言本教程范例</title>
</head>
<body bgcolor="#ffffff" leftmargin="0" topmargin="0"
marginwidth="0" marginheight="0">
<template:get name='header'/>
<template:get name='content'/>
<template:get name='footer'/>
</body>
</html>
<%@ taglib uri='/WEB-INF/struts-template.tld' prefix='template' %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<template:insert template='/template.jsp'>
<template:put name='header' content='/header.htm'/>
<template:put name='content' content='/lyList.do'/>
<template:put name='footer' content='/footer.htm'/>
</template:insert>
<table width="90%" height="50" border="0" align="center"
cellpadding="0" cellspacing="0">
<tr>
<td align="center"><strong>留 言 本</strong></td>
</tr>
</table>
<table width="90%" border="0" align="center" cellpadding="0"
cellspacing="0">
<tr>
<td align="center">留言本教程范例 2003-9-21</td>
</tr>
</table>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<jsp:useBean id="lyList" scope="session"
type="java.util.ArrayList"/>
<table width="90%" border="0" align="center" cellpadding="0"
cellspacing="0">
<tr>
<td align="right"><html:link page="/editLy.do?action=Add">我要
留言</html:link> </td>
</tr>
</table>
<logic:iterate id="value" name="lyList"
type="guestbook.maxuan.ejb.entity.value.BookValue"
indexId="index">
<table width="90%" border="0" align="center"
cellpadding="5" cellspacing="2">
<tr>
<td><font size="4"><b><bean:write
name="value" property="name"/></b></font><br>
Email:<a href='mailto:<bean:write
name="value" property="email"/>'><bean:write name="value"
property="email"/></a>
QQ:<bean:write name="value" property="qq"/> <br>
留言時間:<bean:write name="value"
property="posttime"/><br><br>
<bean:write name="value" property="comment"/></td>
</tr>
<tr>
<td height="1"><hr size="1" noshade></td>
</tr>
</table>
</logic:iterate>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>留言</title>
<meta http-equiv="Content-Type"
content="text/html; charset=gb2312">
</head>
<body>
<table width="70%" border="1" align="center" cellpadding="2"
cellspacing="2"
bordercolor="#000000">
<html:form action="/saveLy">
<tr>
<td width="21%" height="20">姓名</td>
<td width="79%" height="20"><html:text property="name"
size="20"/></td>
</tr>
<tr>
<td height="20">email</td>
<td height="20"><html:text property="email" size="20"/></td>
</tr>
<tr>
<td height="20">qq</td>
<td height="20"><html:text property="qq" size="20"/></td>
</tr>
<tr>
<td height="20">留言內容</td>
<td height="20"><html:textarea property="comment" rows="5"
cols="50"/></td>
</tr>
<tr align="center">
<td height="20" colspan="2"><html:submit>保存</html:submit>
<html:reset>重置</html:reset></td>
</tr>
</html:form>
</table>
</body>
</html>
最后效果如圖:
此時我們的j2ee體系的留言本教程也就告于段落!
從這篇教程我們可以窺見j2ee多層體系結構的端倪,
本篇教程只是一個基石,在此之上,你可以靈活地搭建更大型的應用,
這才是我寫此文的最終目的!
后記:幻想曲花了30多分鐘的時間從經(jīng)典論壇中將maxuan9的帖子整理到了文檔區(qū),
希望對那些想學J2EE和正在學J2EE的朋友一點啟示、一點幫助!
進入討論組討論。
補遺篇
在完成之后,我想我有幾個地方得交待一下!
1.留言排序的問題
按照上面的教程完成之后,我們發(fā)現(xiàn)最新的留言總在后面,而不是最上方,這是因為我們沒有進行排序(我們將信息加入LyList中,它的順序總是add(),最后加入的總排在最后面,而logic:iterator標簽都是從索引0開始顯示到最末,因此我們必須要對此LyList進行排序)
從BookControlBean.java中可以看出,我們使用ejbFinder得到Collection,ArrayList類接受Collection對象構造函數(shù),使Collection轉換為了List。因此我們可以相當簡單的使用Collections.sort()、Collections.reverse()進行排序!
PS:最后一幅完成圖即為排序后的頁面!
2.留言本頁面中文的顯示問題
在前面我們說過為了直接在頁面上輸入中文,我們必須對struts.jar包進行一下改裝
具體的文件為:PropertyMessageResources.java
將第289行的:messages.put(messageKey(localeKey, key),props.getProperty(key));
改成下面的代碼:
String sProps = props.getProperty(key);
try
{
sProps = new String(sProps.getBytes("ISO-8859-1"),"GBK");
}
catch (Exception e)
{
e.printStackTrace();
}
messages.put(messageKey(localeKey, key),sProps);
然后重新編譯生成新包。
為了方便大家,這里我直接提供新包下載
3.留言分頁問題
在此教程中我并沒有寫分頁,其實寫分頁相當簡單,看看文檔中的logic:iterator,提示:length和offset,發(fā)揮一下想像就能寫出來!呵呵,自己慢慢進級吧,自己獨立解決才是真正的樂趣所在!
至此,如果您對此教程還有什么疑問的話請PM我??!
拷貝代碼的話可以去下面這個地址:
實戰(zhàn)留言簿(EJB,Struts應用篇)
[全文完]
(出處:http://m.survivalescaperooms.com)
新聞熱點
疑難解答