J2EE项目:整合SSH开发『新闻发布系统』

来源:互联网 发布:centos vsftpd 端口 编辑:程序博客网 时间:2024/06/06 00:02
 
一、架构
    Struts
+Spring+Hibernate

二、Hibernate持久层
1.编写PO类
====================================================================================
package org.prolove.model;

import java.io.Serializable;


/**
 * Base class for Model objects.  Child objects should implement toString(), 
 * equals() and hashCode();
 *
 * <p>
 * <a href="BaseObject.java.html"><i>View Source</i></a>
 * </p>
 *
 * 
@author <a href="mailto:prolove@live.cn">PROLOVE</a>
 
*/

public abstract class BaseObject implements Serializable {    
    
public abstract String toString();
    
public abstract boolean equals(Object o);
    
public abstract int hashCode();
}

====================================================================================
package org.prolove.model;

import java.util.Date;
import java.util.Set;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * @hibernate.class table="news"
 * @struts.form include-all="false" extends="BaseForm"
 
*/

public class News extends BaseObject {

    
private Long id;// pk,required

    
private String title;// required

    
private String content;// required

    
private User poster;// fk,required

    
private Date postDate;// required

    
private Date lastModifyDate;// required

    
private Category category;// required

    
private Set newsReviews;

    
public News() {
    }


    
/**
     * 
@return Returns the newsReview.
     
*/

    
public Set getNewsReviews() {
        
return newsReviews;
    }


    
/**
     * 
@param newsReview
     *            The newsReview to set.
     
*/

    
public void setNewsReviews(Set newsReviews) {
        
this.newsReviews = newsReviews;
    }


    
/**
     * @hibernate.many-to-one column="id" not-null="true"
     
*/

    
public Category getCategory() {
        
return category;
    }


    
public void setCategory(Category category) {
        
this.category = category;
    }


    
/**
     * @hibernate.property column="last_modify_date" not-null="true"
     
*/

    
public Date getLastModifyDate() {
        
return lastModifyDate;
    }


    
public void setLastModifyDate(Date lastModifyDate) {
        
this.lastModifyDate = lastModifyDate;
    }


    
/**
     * @hibernate.property column="post_date" not-null="true"
     
*/

    
public Date getPostDate() {
        
return postDate;
    }


    
public void setPostDate(Date postDate) {
        
this.postDate = postDate;
    }


    
/**
     * @hibernate.many-to-one column="username" not-null="true"
     
*/

    
public User getPoster() {
        
return poster;
    }


    
public void setPoster(User poster) {
        
this.poster = poster;
    }


    
/**
     * @hibernate.property column="content" length="3000" not-null="true"
     
*/

    
public String getContent() {
        
return content;
    }


    
public void setContent(String content) {
        
this.content = content;
    }


    
/**
     * 
@return Returns the id.
     * @hibernate.id column="id" generator-class="increment"
     *               unsaved-value="null"
     
*/

    
public Long getId() {
        
return id;
    }


    
public void setId(Long id) {
        
this.id = id;
    }


    
/**
     * @hibernate.property column="title" length="50" not-null="true"
     
*/

    
public String getTitle() {
        
return title;
    }


    
public void setTitle(String title) {
        
this.title = title;
    }


    
/**
     * 
@see java.lang.Object#equals(Object)
     
*/

    
public boolean equals(Object object) {
        
if (!(object instanceof News)) {
            
return false;
        }

        News rhs 
= (News) object;
        
return this.poster.equals(rhs.getPoster())
                
&& this.postDate.equals(rhs.getPostDate());
        
/*
         * return new EqualsBuilder().append(this.newsReviews, rhs.newsReviews)
         * .append(this.title, rhs.title).append(this.category,
         * rhs.category).append(this.content, rhs.content).append(
         * this.postDate, rhs.postDate).append( this.lastModifyDate,
         * rhs.lastModifyDate).append( this.id, rhs.id).append(this.poster,
         * rhs.poster) .isEquals();
         
*/

    }


    
/**
     * 
@see java.lang.Object#hashCode()
     
*/

    
public int hashCode() {
        
return this.poster.hashCode() + this.postDate.hashCode();
        
/*
         * return new HashCodeBuilder(1595611275, -1477459617).append(
         * this.newsReviews).append(this.title).append(this.category)
         * .append(this.content).append(this.postDate).append(
         * this.lastModifyDate).append(this.id)
         * .append(this.poster).toHashCode();
         
*/

    }


    
/**
     * 
@see java.lang.Object#toString()
     
*/

    
public String toString() {
        
return new ToStringBuilder(this).append("id"this.id).append("title",
                
this.title).append("postDate"this.postDate).append("content",
                
this.content).append("lastModifyDate"this.lastModifyDate)
                .append(
"poster"this.poster)
                .append(
"category"this.category).append("newsReviews",
                        
this.newsReviews).toString();
    }


}


2.编写PO的映射配置文件
====================================================================================
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
    
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

    
<class name="org.prolove.model.News" table="news">

        
<id name="id" column="id" unsaved-value="null">

            
<!-- The generator-class attribute of @hibernate.id is deprecated, use the @hibernate.generator tag instead -->
            
<generator class="increment">

            
</generator>

        
</id>

        
<many-to-one name="category" class="org.prolove.model.Category" column="category_id" not-null="true">

        
</many-to-one>

        
<property name="lastModifyDate" column="last_modify_date" not-null="true">

        
</property>

        
<property name="postDate" column="post_date" not-null="true">

        
</property>

        
<many-to-one name="poster" column="username" not-null="true">

        
</many-to-one>

        
<property name="content" column="content" length="3000" not-null="true">

        
</property>

        
<property name="title" column="title" length="50" not-null="true">

        
</property>
        
<!-- bi-directional one-to-many association to NewsReview -->
        
<set name="newsReviews" lazy="false" inverse="true" cascade="all-delete-orphan">
            
<meta attribute="field-description">
                @hibernate.list lazy
="true" inverse="false" cascade="none"

                @hibernate.collection
-key column="id"

                @hibernate.collection
-one-to-many class="org.prolove.model.NewsReview"
            
</meta>
            
<key>
                
<column name="news_id" />
            
</key>
            
<one-to-many class="org.prolove.model.NewsReview" />
        
</set>
    
</class>

</hibernate-mapping>

3.连接数据库
applicationContext
-hibernate.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        
<!-- property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/--> 
        
<property name="url" value="jdbc:oracle:thin:@10.200.3.81:1521:oranet"/>
        
<property name="username" value="hm"/>
        
<property name="password" value="hm123"/>
        
<property name="maxActive" value="100"/>
        
<property name="maxIdle" value="30"/>
        
<property name="maxWait" value="1000"/>
        
<property name="defaultAutoCommit" value="true"/>
        
<property name="removeAbandoned" value="true"/>
        
<property name="removeAbandonedTimeout" value="60"/>
        
<property name="logAbandoned" value="true"/>
    
</bean>    
    
<!-- Hibernate SessionFactory -->
    
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        
<property name="dataSource" ref="dataSource"/>
        
<property name="mappingResources">
            
<list>
                
<value>org/prolove/model/User.hbm.xml</value>
                
<value>org/prolove/model/News.hbm.xml</value>
                
<value>org/prolove/model/NewsReview.hbm.xml</value>
                
<value>org/prolove/model/Category.hbm.xml</value>
            
</list>
        
</property>
        
<!-- The property below is commented out b/c it doesn't work when run via
             Ant in Eclipse.  It works fine for individual JUnit tests and in IDEA ??
        
<property name="mappingJarLocations">
            
<list><value>file:dist/appfuse-dao.jar</value></list>
        
</property>
        
-->
        
<property name="hibernateProperties">
            
<props>
                
<prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
                
<!-- Create/update the database tables automatically when the JVM starts up
                
<prop key="hibernate.hbm2ddl.auto">update</prop> -->
                
<!-- Turn batching off for better error messages under PostgreSQL 
                
<prop key="hibernate.jdbc.batch_size">0</prop> -->
            
</props>
        
</property>
    
</bean>

    
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>

    
<!-- Generic DAO - can be used when doing standard CRUD -->
    
<bean id="dao" class="org.prolove.dao.hibernate.BaseDAOHibernate">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>

    
<!-- UserDAO: Hibernate implementation -->
    
<bean id="userDAO" class="org.prolove.dao.hibernate.UserDAOHibernate">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>

    
<!-- Add new DAOs here -->
    
<bean id="newsDAO" class="org.prolove.dao.hibernate.NewsDAOHibernate">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>
    
<bean id="newsReviewDAO" class="org.prolove.dao.hibernate.NewsReviewDAOHibernate">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>
    
<bean id="categoryDAO" class="org.prolove.dao.hibernate.CategoryDAOHibernate">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>
    
<!-- PersonDAO: Hibernate implementation --> 
    
<bean id="personDAO" class="org.appfuse.dao.hibernate.PersonDAOHibernate"> 
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>        
</beans>

=====================================================================
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<!-- hibernate datasource-->
    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        
<property name="url" value="jdbc:mysql://localhost:3306/newsboard"/>
        
<property name="username" value="root"/>
        
<property name="password" value="root"/>
        
<property name="maxActive" value="20"/>
        
<property name="maxIdle" value="10"/>
        
<property name="initialSize" value="1"/>
        
<property name="maxWait" value="1000"/>
        
<property name="defaultAutoCommit" value="true"/>
        
<property name="removeAbandoned" value="true"/>
        
<property name="removeAbandonedTimeout" value="60"/>
        
<property name="logAbandoned" value="true"/>
    
</bean>    
    
<!-- Hibernate SessionFactory -->
    
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        
<property name="dataSource" ref="dataSource"/>
        
<property name="mappingResources">
            
<list>
                
<value>org/prolove/model/User.hbm.xml</value>
                
<value>org/prolove/model/News.hbm.xml</value>
                
<value>org/prolove/model/NewsReview.hbm.xml</value>
                
<value>org/prolove/model/Category.hbm.xml</value>
            
</list>
        
</property>
        
<property name="hibernateProperties">
            
<props>
                
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                
<prop key="hibernate.hbm2ddl.auto">update</prop>
                
<prop key="hibernate.jdbc.batch_size">20</prop> 
            
</props>
        
</property>
    
</bean>

    
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
    
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>


    
<!-- service manager Template-->
    
<bean id="txProxyTemplate" abstract="true"
        
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        
<property name="transactionManager" ref="transactionManager"/>
        
<property name="transactionAttributes">
            
<props>
                
<prop key="save*">PROPAGATION_REQUIRED</prop>
                
<prop key="remove*">PROPAGATION_REQUIRED</prop>
                
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            
</props>
        
</property>
    
</bean>

    
<!-- service manager-->
    
<bean id="facadeManager" parent="txProxyTemplate">
        
<property name="target">
            
<bean class="org.prolove.service.impl.FacadeManagerImpl">
                
<property name="newsDAO" ref="newsDAO"/>
                
<property name="newsReviewDAO" ref="newsReviewDAO"/>
                
<property name="categoryDAO" ref="categoryDAO"/>
                
<property name="userDAO" ref="userDAO"/>
            
</bean>
        
</property>
    
</bean>

</beans>

三、DAO组件层
1.DAO组件的结构
    为了让逻辑组件与具体的DAO组件分离,还必须有一个DAO工厂。

2.编写DAO接口
package org.prolove.dao;

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


/**
 * Data Access Object (DAO) interface.   This is an interface
 * used to tag our DAO classes and to provide common methods to all DAOs.
 *
 * <p><a href="DAO.java.html"><i>View Source</i></a></p>
 *
 * 
@author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 
*/

public interface DAO {

    
/**
     * Generic method used to get all objects of a particular type. This
     * is the same as lookup up all rows in a table.
     * 
@param clazz the type of objects (a.k.a. while table) to get data from
     * 
@return List of populated objects
     
*/

    
public List getObjects(Class clazz);
    
    
/**
     * Generic method to get an object based on class and identifier. An 
     * ObjectRetrievalFailureException Runtime Exception is thrown if 
     * nothing is found.
     * 
     * 
@param clazz model class to lookup
     * 
@param id the identifier (primary key) of the class
     * 
@return a populated object
     * 
@see org.springframework.orm.ObjectRetrievalFailureException
     
*/

    
public Object getObject(Class clazz, Serializable id);

    
/**
     * Generic method to save an object - handles both update and insert.
     * 
@param o the object to save
     
*/

    
public void saveObject(Object o);

    
/**
     * Generic method to delete an object based on class and id
     * 
@param clazz model class to lookup
     * 
@param id the identifier (primary key) of the class
     
*/

    
public void removeObject(Class clazz, Serializable id);
}


=========================================================================

package org.prolove.dao;

import java.util.List;

import org.prolove.model.User;

/**
 * User Data Access Object (DAO) interface.
 *
 * <p>
 * <a href="UserDAO.java.html"><i>View Source</i></a>
 * </p>
 *
 * 
@author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 
*/

public interface UserDAO extends DAO {
    
/**
     * Gets users information based on login name.
     * 
@param username the current username
     * 
@return user populated user object
     
*/

    
public User getUser(String username);

    
/**
     * Gets a list of users based on parameters passed in.
     *
     * 
@return List populated list of users
     
*/

    
public List getUsers(User user);

    
/**
     * Saves a user's information
     * 
@param user the object to be saved
     
*/

    
public void saveUser(User user);

    
/**
     * Removes a user from the database by id
     * 
@param username the user's username
     
*/

    
public void removeUser(String username);
}

……

3.编写DAO的具体实现
package org.prolove.dao.hibernate;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.prolove.dao.DAO;

/**
 * This class serves as the Base class for all other DAOs - namely to hold
 * common methods that they might all use. Can be used for standard CRUD
 * operations.</p>
 *
 * <p><a href="BaseDAOHibernate.java.html"><i>View Source</i></a></p>
 *
 * 
@author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 
*/

public class BaseDAOHibernate extends HibernateDaoSupport implements DAO {
    
protected final Log log = LogFactory.getLog(getClass());
    
/**
     * 
@see org.leecode.dao.DAO#saveObject(java.lang.Object)
     
*/

    
public void saveObject(Object o) {
        getHibernateTemplate().saveOrUpdate(o);
    }


    
/**
     * 
@see org.leecode.dao.DAO#getObject(java.lang.Class, java.io.Serializable)
     
*/

    
public Object getObject(Class clazz, Serializable id) {
        Object o 
= getHibernateTemplate().get(clazz, id);

        
if (o == null{
            
throw new ObjectRetrievalFailureException(clazz, id);
        }


        
return o;
    }


    
/**
     * 
@see org.leecode.dao.DAO#getObjects(java.lang.Class)
     
*/

    
public List getObjects(Class clazz) {
        
return getHibernateTemplate().loadAll(clazz);
    }


    
/**
     * 
@see org.leecode.dao.DAO#removeObject(java.lang.Class, java.io.Serializable)
     
*/

    
public void removeObject(Class clazz, Serializable id) {
        getHibernateTemplate().delete(getObject(clazz, id));
    }

}


======================================================================================

package org.prolove.dao.hibernate;

import org.springframework.orm.ObjectRetrievalFailureException;
import org.prolove.dao.NewsDAO;
import org.prolove.model.News;

public class NewsDAOHibernate extends BaseDAOHibernate implements NewsDAO {

    
public News getNews(Long id) {
        News news 
= (News) getHibernateTemplate().get(News.class, id);

        
if (news == null{
            
throw new ObjectRetrievalFailureException(News.class, id);   
        }


        
return news;
    }


    
public void saveNews(News news) {
        getHibernateTemplate().saveOrUpdate(news);
    }


    
public void removeNews(Long id) {
        
// object must be loaded before it can be deleted
        getHibernateTemplate().delete(getNews(id));
    }

}

……

4.用Spring容器代替DAO工厂
    见上文applicationContext
-hibernate.xml
以及
daoContext.xml
<?xml version="1.0" encoding="GBK"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
    
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    
<!--  DAO模板,用于被其他的DAO组件继承 -->
    
<bean id="daoTemplate" abstract="true" lazy-init="true">
        
<property name="sessionFactory" ref="sessionFactory"/>
    
</bean>

    
<!-- Generic DAO - can be used when doing standard CRUD -->
    
<bean id="dao" class="org.prolove.dao.hibernate.BaseDAOHibernate"
        parent
="daoTemplate"/>

    
<!-- UserDAO: Hibernate implementation -->
    
<bean id="userDAO" class="org.prolove.dao.hibernate.UserDAOHibernate"
        parent
="daoTemplate"/>

    
<!-- NewsDAO Hibernate implementation -->
    
<bean id="newsDAO" class="org.prolove.dao.hibernate.NewsDAOHibernate"
        parent
="daoTemplate"/>

    
<!-- NewsReviewDAO Hibernate implementation -->
    
<bean id="newsReviewDAO" class="org.prolove.dao.hibernate.NewsReviewDAOHibernate"
        parent
="daoTemplate"/>

    
<!-- CategoryDAO Hibernate implementation -->
    
<bean id="categoryDAO" class="org.prolove.dao.hibernate.CategoryDAOHibernate"
        parent
="daoTemplate"/>

</beans>

四、业务逻辑层
1.业务逻辑组件的结构
    每个模块设计一个业务逻辑组件。

2.业务逻辑组件的接口
package org.prolove.service;

import java.util.List;

import org.prolove.dao.CategoryDAO;
import org.prolove.dao.NewsDAO;
import org.prolove.dao.NewsReviewDAO;
import org.prolove.dao.UserDAO;
import org.prolove.model.Category;
import org.prolove.model.News;
import org.prolove.model.NewsReview;
import org.prolove.model.User;

//该接口是对DAO的正面包装
public interface FacadeManager {
    
// category的业务方法
    public void setCategoryDAO(CategoryDAO dao);

    
public Category getCategory(String id);

    
public void saveCategory(Category category);

    
public void removeCategory(String id);

    
public List getCategories();

    
// news的业务方法
    public void setNewsDAO(NewsDAO dao);

    
public News getNews(String id);

    
public void saveNews(News news);

    
public void removeNews(String id);

    
// newsReview的业务方法
    public void setNewsReviewDAO(NewsReviewDAO dao);

    
public NewsReview getNewsReview(String id);

    
public void saveNewsReview(NewsReview newsReview);

    
public void removeNewsReview(String id);

    
// user的业务方法
    public void setUserDAO(UserDAO dao);

    
public User getUser(String username);

    
public List getUsers(User user);

    
public void saveUser(User user) throws Exception;

    
public void removeUser(String username);

    
public boolean validateUser(User user);
}


3.业务逻辑组件的实现类
package org.prolove.service;

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

import org.prolove.dao.DAO;

public interface Manager {
    
    
/**
     * Expose the setDAO method for testing purposes
     * 
@param dao
     
*/

    
public void setDAO(DAO dao);
    
    
/**
     * Generic method used to get a all objects of a particular type. 
     * 
@param clazz the type of objects 
     * 
@return List of populated objects
     
*/

    
public List getObjects(Class clazz);
    
    
/**
     * Generic method to get an object based on class and identifier. 
     * 
     * 
@param clazz model class to lookup
     * 
@param id the identifier (primary key) of the class
     * 
@return a populated object 
     * 
@see org.springframework.orm.ObjectRetrievalFailureException
     
*/

    
public Object getObject(Class clazz, Serializable id);

    
/**
     * Generic method to save an object.
     * 
@param o the object to save
     
*/

    
public void saveObject(Object o);

    
/**
     * Generic method to delete an object based on class and id
     * 
@param clazz model class to lookup
     * 
@param id the identifier of the class
     
*/

    
public void removeObject(Class clazz, Serializable id);
}


package org.prolove.service.impl;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.prolove.dao.DAO;
import org.prolove.service.Manager;

/**
 * Base class for Business Services - use this class for utility methods and
 * generic CRUD methods.
 * 
 * <p><a href="BaseManager.java.html"><i>View Source</i></a></p>
 *
 * 
@author <a href="mailto:prolove@live.cn">Matt Raible</a>
 
*/

public class BaseManager implements Manager {
    
protected DAO dao = null;
    
protected final Log log = LogFactory.getLog(getClass());    
    
/**
     * 
@see org.leecode.service.Manager#setDAO(org.leecode.dao.DAO)
     
*/

    
public void setDAO(DAO dao) {
        
this.dao = dao;
    }

    
    
/**
     * 
@see org.leecode.service.Manager#getObject(java.lang.Class, java.io.Serializable)
     
*/

    
public Object getObject(Class clazz, Serializable id) {
        
return dao.getObject(clazz, id);
    }

    
    
/**
     * 
@see org.leecode.service.Manager#getObjects(java.lang.Class)
     
*/

    
public List getObjects(Class clazz) {
        
return dao.getObjects(clazz);
    }

    
    
/**
     * 
@see org.leecode.service.Manager#removeObject(java.lang.Class, java.io.Serializable)
     
*/

    
public void removeObject(Class clazz, Serializable id) {
        dao.removeObject(clazz, id);
    }

    
    
/**
     * 
@see org.leecode.service.Manager#saveObject(java.lang.Object)
     
*/

    
public void saveObject(Object o) {
        dao.saveObject(o);
    }

}


package org.prolove.service.impl;

import java.util.List;

import org.springframework.dao.DataIntegrityViolationException;
import org.prolove.dao.CategoryDAO;
import org.prolove.dao.NewsDAO;
import org.prolove.dao.NewsReviewDAO;
import org.prolove.dao.UserDAO;
import org.prolove.model.Category;
import org.prolove.model.News;
import org.prolove.model.NewsReview;
import org.prolove.model.User;
import org.prolove.service.FacadeManager;

public class FacadeManagerImpl extends BaseManager implements
        FacadeManager 
{
    
private CategoryDAO categoryDAO;

    
private NewsDAO newsDAO;

    
private NewsReviewDAO newsReviewDAO;

    
private UserDAO userDAO;

    
public void setCategoryDAO(CategoryDAO categoryDAO) {
        
this.categoryDAO = categoryDAO;
    }


    
public Category getCategory(String id) {
        
return categoryDAO.getCategory(Long.valueOf(id));
    }


    
public void saveCategory(Category category) {
        categoryDAO.saveCategory(category);
    }


    
public void removeCategory(String id) {
        categoryDAO.removeCategory(Long.valueOf(id));
    }


    
public List getCategories() {
        
return categoryDAO.getCategories();
    }


    
public void setNewsDAO(NewsDAO newsDAO) {
        
this.newsDAO = newsDAO;
    }


    
public News getNews(String id) {
        
return newsDAO.getNews(Long.valueOf(id));
    }


    
public void saveNews(News news) {
        newsDAO.saveNews(news);
    }


    
public void removeNews(String id) {
        newsDAO.removeNews(Long.valueOf(id));
    }


    
public void setNewsReviewDAO(NewsReviewDAO newsReviewDAO) {
        
this.newsReviewDAO = newsReviewDAO;
    }


    
public NewsReview getNewsReview(String id) {
        
return newsReviewDAO.getNewsReview(Long.valueOf(id));
    }


    
public void saveNewsReview(NewsReview newsReview) {
        newsReviewDAO.saveNewsReview(newsReview);
    }


    
public void removeNewsReview(String id) {
        newsReviewDAO.removeNewsReview(Long.valueOf(id));
    }


    
public void setUserDAO(UserDAO userDAO) {
        
this.userDAO = userDAO;
    }


    
public User getUser(String username) {
        
return userDAO.getUser(username);
    }


    
public List getUsers(User user) {
        
return userDAO.getUsers(user);
    }


    
public void saveUser(User user) throws Exception {
        
try {
            userDAO.saveUser(user);
        }
 catch (DataIntegrityViolationException e) {
            
throw new Exception("User '" + user.getUsername()
                    
+ "' already exists!");
        }

    }


    
public void removeUser(String username) {
        userDAO.removeUser(username);
    }


    
public boolean validateUser(User aUser) {
        User user 
= getUser(aUser.getUsername());
        
if (user != null && user.getPassword().equals(aUser.getPassword()))
            
return true;
        
else
            
return false;
    }

}


4.业务逻辑组件的配置
    在applicationContext.xml配置FacadeManager组件

五、Web层设计
1.Action的实现
package org.prolove.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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.validator.DynaValidatorForm;

import org.prolove.action.base.BaseAction;
import org.prolove.webapp.util.AppConstants;
import org.prolove.model.*;

import java.util.*;

/**
 * 
@author  PROLOVE prolve@live.cn
 * 
@version  1.0
 * <br>Copyright (C), 2006-2008, PROLOVE
 * <br>This program is protected by copyright laws.
 * <br>Program Name:
 * <br>Date: 
 
*/

public class AddReviewAction extends BaseAction
{
    
//必须重写该核心方法,该方法actionForm将表单的请求参数封装成值对象
    public ActionForward execute(ActionMapping mapping, ActionForm form,
       HttpServletRequest request, HttpServletResponse response)
throws Exception
    
{
        DynaValidatorForm addForm 
= (DynaValidatorForm)form;
        String content 
= (String)addForm.get("content");
        String newsId 
= (String)addForm.get("newsId");

        
try
        
{
            News news 
= mgr.getNews(newsId);
            String username 
= (String)request.getSession(true).getAttribute(AppConstants.LOGIN_USER);        
            User poster 
= mgr.getUser(username);

            NewsReview newsReview 
= new NewsReview();
            newsReview.setNews(news);
            newsReview.setPoster(poster);
            newsReview.setContent(content);
            newsReview.setPostDate(
new Date());
            newsReview.setLastModifyDate(
new Date());
            mgr.saveNewsReview(newsReview);
        }

        
catch (Exception e)
        
{
            request.setAttribute(
"newsId" , newsId);
            
return mapping.findForward("failure");
        }

        request.setAttribute(
"newsId" , newsId);
        
return mapping.findForward("success");
    }

}


package org.prolove.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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.validator.DynaValidatorForm;

import org.prolove.action.base.BaseAction;
import org.prolove.model.News;

import java.util.Set;

/**
 * 
@author  PROLOVE prolve@live.cn
 * 
@version  1.0
 * <br>Copyright (C), 2006-2008, PROLOVE
 * <br>This program is protected by copyright laws.
 * <br>Program Name:
 * <br>Date: 
 
*/

public class LoadReviewsByNews extends BaseAction
{
    
//必须重写该核心方法,该方法actionForm将表单的请求参数封装成值对象
    public ActionForward execute(ActionMapping mapping, ActionForm form,
       HttpServletRequest request, HttpServletResponse response)
throws Exception
    
{
        String newsId 
= null;        
        
if(request.getAttribute("newsId"== null)
        
{
            newsId 
= request.getParameter("newsId");
        }

        
else
        
{
            newsId 
= (String)request.getAttribute("newsId");
        }

        News news 
= mgr.getNews(newsId);
        request.setAttribute(
"news" , news);
        request.setAttribute(
"reviews",news.getNewsReviews());        
        
return mapping.findForward("success");
    }

}

……

2.Spring管理容器Action
    采用DelegatingRequestProcessor的整合策略。
struts
-config.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts-config PUBLIC
          
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          
"http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
    
<form-beans>
        
<!--  配置登陆所使用的Form-->
        
<form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm">
            
<form-property name="user" type="java.lang.String" />
            
<form-property name="pass" type="java.lang.String" />
        
</form-bean>

        
<!--  添加新闻所用的Form-->
        
<form-bean name="addNewsForm" type="org.apache.struts.validator.DynaValidatorForm">
            
<form-property name="title" type="java.lang.String" />
            
<form-property name="content" type="java.lang.String" />
            
<form-property name="categoryId" type="java.lang.String" />
        
</form-bean>

        
<!--  添加新闻评论所用的Form-->
        
<form-bean name="addNewsReviewForm" type="org.apache.struts.validator.DynaValidatorForm">
            
<form-property name="content" type="java.lang.String" />
            
<form-property name="newsId" type="java.lang.String" />
        
</form-bean>

    
</form-beans>

    
<global-forwards>
    
</global-forwards>

    
<!-- ========================================= Action Mapping Definitions -->
    
<action-mappings>
        
<!--  处理登陆  -->
        
<action path="/processLogin"
                name
="loginForm" 
                scope
="request"
                validate
="true" 
                input
="input">
            
<forward name="input" path="/index.jsp" />
            
<forward name="success" path="/listCate.do" />
        
</action>

        
<!--  登出系统  -->
        
<action path="/logout" scope="request">
            
<forward name="success" path="/index.jsp"/>
        
</action>

        
<!--  进入主页面  -->
        
<action path="/listCate" scope="request">
            
<forward name="success" path="/main.jsp"/>
        
</action>

        
<!--  根据种类加载所有新闻  -->
        
<action path="/loadNewsByCategory" scope="request">
            
<forward name="failure" path="/listCate.do"/>
            
<forward name="success" path="/category_view.jsp"/>
        
</action>

        
<!--  添加新闻  -->
        
<action path="/addNews"
                name
="addNewsForm" 
                scope
="request"
                validate
="true" 
                input
="input">
            
<forward name="failure" path="/loadNewsByCategory.do"/>
            
<forward name="success" path="/loadNewsByCategory.do"/>
        
</action>

        
<!--  根据新闻id加载所有评论  -->
        
<action path="/loadNewsReviewByNews" scope="request">
            
<forward name="success" path="/news_view.jsp"/>
        
</action>

        
<!--  添加新闻评论  -->
        
<action path="/addNewsReview"
                name
="addNewsReviewForm" 
                scope
="request"
                validate
="true" 
                input
="input">
            
<forward name="failure" path="/loadNewsReviewByNews.do"/>
            
<forward name="success" path="/loadNewsReviewByNews.do"/>
        
</action>

    
</action-mappings>

    
<controller inputForward="true" processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>

    
<message-resources parameter="resource"/>

    
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
        
<set-property property="pathnames" value="/WEB-INF/validator-rules.xml,
                                              /WEB-INF/validation.xml"/>
        <set-property property="stopOnFirstError" value="true"/>
    
</plug-in>


    
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
        
<set-property property="contextConfigLocation" value="/WEB-INF/daoContext.xml,
                                                              /WEB-INF/applicationContext.xml,
                                                              
/WEB-INF/action-Servlet.xml"/>
    </plug-in>


</struts-config>

action
-Servlet.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    
<bean id="actionTemplate" abstract="true" singleton="false">
        
<property name="mgr" ref="facadeManager"/>
    
</bean>

    
<!--  处理登陆-->
    
<bean name="/processLogin" class="org.prolove.action.LoginAction" parent="actionTemplate"/>
    
<!--  登出系统-->
    
<bean name="/logout" class="org.prolove.action.Logout"/>
    
<!--  列出所有的新闻分类-->
    
<bean name="/listCate" class="org.prolove.action.ListCate" parent="actionTemplate"/> 
    
<!--  根据种类列出所有新闻-->
    
<bean name="/loadNewsByCategory" class="org.prolove.action.LoadNewsByCategory" parent="actionTemplate"/>
    
<!--  添加新闻-->
    
<bean name="/addNews" class="org.prolove.action.AddNewsAction" parent="actionTemplate"/>
    
<!--  根据新闻查看所有的评论-->
    
<bean name="/loadNewsReviewByNews" class="org.prolove.action.LoadReviewsByNews" parent="actionTemplate"/>
    
<!--  添加新闻评论-->
    
<bean name="/addNewsReview" class="org.prolove.action.AddReviewAction" parent="actionTemplate"/>
    
</beans>

3.数据校验的选择
validation.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE form-validation PUBLIC
          
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN"
          
"http://jakarta.apache.org/commons/dtds/validator_1_1_3.dtd">
<form-validation>
    
<formset>
        
<form name="loginForm">
            
<field property="user" depends="required,minlength">
                
<arg key="loginForm.user" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>4</var-value>
                
</var>
            
</field>
            
<field property="pass" depends="required,minlength">
                
<arg key="loginForm.pass" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>4</var-value>
                
</var>
            
</field>
        
</form>


        
<form name="addNewsForm">
            
<field property="title" depends="required">
                
<arg key="addNewsForm.title" position="0"/>
            
</field>
            
<field property="content" depends="required">
                
<arg key="addNewsForm.content" position="0"/>
            
</field>
            
<field property="categoryId" depends="required,integer">
                
<arg key="addNewsForm.categoryId" position="0"/>
            
</field>
        
</form>

        
<form name="addNewsReviewForm">
            
<field property="content" depends="required">
                
<arg key="addNewsReviewForm.content" position="0"/>
            
</field>
            
<field property="newsId" depends="required,integer">
                
<arg key="addNewsReviewForm.categoryId" position="0"/>
            
</field>
        
</form>

  
</formset>
</form-validation>

4.访问权限的控制
package org.prolove.webapp.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.prolove.webapp.util.AppConstants;

/**
 * 设置字符集、过滤未登录的非法请求
 
*/

public class UserLoginFilter implements Filter {
    
protected String encoding = null;

    
protected FilterConfig filterConfig = null;

    
protected boolean ignore = false;

    
protected String forwardPath = null;

    
public void destroy() {
        
this.encoding = null;
        
this.filterConfig = null;
    }


    
public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) 
throws IOException, ServletException {

        
// 设置编码方式,web.xml里面有filter参数的初始化设置
        if (ignore || (request.getCharacterEncoding() == null)) {
            String encoding 
= selectEncoding(request);
            
if (encoding != null)
                request.setCharacterEncoding(encoding);
        }

        HttpServletRequest httpServletRequest 
= (HttpServletRequest) request;
        HttpServletResponse httpServletResponse 
= (HttpServletResponse) response;
        String requesturi 
= httpServletRequest.getRequestURI();
        
// 通过检查session中的变量,过虑请求
        HttpSession session = httpServletRequest.getSession();
        Object currentUser 
= session.getAttribute(AppConstants.LOGIN_USER);
        
// 当前会话用户为空而且不是请求登录,退出登录,欢迎页面和根目录则退回到应用的根目录
        if (currentUser == null
                
&& !requesturi.endsWith("/processLogin.do")
                
&& !requesturi.endsWith("/logout.do")
                
&& !requesturi.endsWith("/index.jsp")
                
&& !requesturi.endsWith(httpServletRequest.getContextPath()
                        
+ "/")) {
            httpServletResponse.sendRedirect(httpServletRequest
                    .getContextPath()
                    
+ "/");
            
return;
        }

        chain.doFilter(request, response);
    }


    
public void init(FilterConfig filterConfig) throws ServletException {
        
this.filterConfig = filterConfig;
        
this.encoding = filterConfig.getInitParameter("encoding");
        
this.forwardPath = filterConfig.getInitParameter("forwardpath");
        String value 
= filterConfig.getInitParameter("ignore");
        
if (value == null)
            
this.ignore = true;
        
else if (value.equalsIgnoreCase("true"))
            
this.ignore = true;
        
else if (value.equalsIgnoreCase("yes"))
            
this.ignore = true;
        
else
            
this.ignore = false;
    }


    
protected String selectEncoding(ServletRequest request) {
        
return (this.encoding);
    }

}


5.解决中文编码问题
    代码同上,另
web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app 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"
    version
="2.4">

      
<filter>
        
<filter-name>Login Filter</filter-name>
        
<filter-class>
            org.prolove.webapp.filter.UserLoginFilter
        
</filter-class>
        
<init-param>
            
<param-name>encoding</param-name>
            
<param-value>GBK</param-value>
        
</init-param>
        
<init-param>
            
<param-name>ignore</param-name>
            
<param-value>false</param-value>
        
</init-param>
        
<init-param>
            
<param-name>forwardpath</param-name>
            
<param-value>index.jsp</param-value>
        
</init-param>
    
</filter>

    
<filter-mapping>
        
<filter-name>Login Filter</filter-name>
        
<url-pattern>/*</url-pattern>
    </filter-mapping>    

    <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>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>


    <jsp-config>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
        <taglib>
            <taglib-uri>/tags/struts-bean</taglib-uri>
            <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>/tags/struts-html</taglib-uri>
            <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
        </taglib>
        <taglib>
            <taglib-uri>/tags/struts-logic</taglib-uri>
            <taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
        </taglib>
    </jsp-config>
</web-app>

6.JSP页面输出
-->main.jsp
<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ include file="taglibs.jsp"%>

<html>
<head>
    <title>版面分类</title>
    <link href="styles/news.css" rel="stylesheet" type="text/css">
</head>
<script language="javascript">
    function verifyValue(){
        if(loadNewsForm.categoryId.checked)
        {
            loadNewsForm.submit();
            return true;
        }
        for (var i = 0 ; i < loadNewsForm.categoryId.length ; i++)
        {
            if( loadNewsForm.categoryId[i].checked )
            {
                loadNewsForm.submit();
                return true;
            }
        }
        alert('请选择要查看的版面!');
        return false;    
    }
    function logout(){
        logoutForm.submit();
    }    
</script>
<body>
    
    <table width="500" align="center" cellpadding="1" bgcolor="#99CCCC">
        <form name="loadNewsForm" action="loadNewsByCategory.do" method="POST"> 
                <tr>
                    <td width="40%" colspan="2" align="center">
                        <p>欢迎,<bean:write name="login_user"/></p>
                    </td>
                </tr>
                <tr>
                    <td width="10%" align="center">
                        请选择
                    </td>
                    <td width="30%" align="center">
                        版面名
                    </td>
                </tr>                
                <logic:iterate id="item" name="categories" indexId="index" scope="request">
                    <tr>
                        <td width="10%" align="center">
                            <input type="radio" name="categoryId" value='<bean:write name="item" property="id"/>'>
                        </td>
                        <td width="30%" align="center">
                            <bean:write name="item" property="name"/>
                        </td>
                    </tr>    
                </logic:iterate>

            <tr>
                <td colspan="2" align="center">
                    <input type="button" value="查看" onClick="verifyValue();">
                    &nbsp;&nbsp;<input type="button" value="登出" onClick="logout();">
                </td>
            </tr>                    
        </form>
        <form name="logoutForm" action="logout.do" method="post"">
        </form>        
</table>
</body>
</html>

-->index.jsp
<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ include file="taglibs.jsp"%>
<html>
<head>
    <title>登陆系统</title>
        <link href="styles/news.css" rel="stylesheet" type="text/css">
</head>
<body>
<logic:messagesPresent>
   <div class="title">    
   <bean:message key="errors.header"/>
   <ul>
   <html:messages id="error">
      <li><bean:write name="error"/></li>
   </html:messages>
   </ul>
   </div>
</logic:messagesPresent>

<logic:present name="errMsg">
    <div class="title">
    <li><bean:write name="errMsg" scope="request"/>
    </div>
</logic:present>
<logic:present name="logout">
    <div class="title">
    <li><bean:write name="logout" scope="request"/>
   </div>
</logic:present>
    <table width="400" align="center" bgcolor="#99CCCC">
        <html:form action="/processLogin"> 
            <tr>
                <td>
                    请输入用户名:
                </td>
                <td>
                    <html:text property="user" size="20"/>
                </td>
            </tr>
            <tr>
                <td>
                    请输入密码:
                </td>
                <td>
                    <input type="password" name="pass" size="20">
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="确定">&nbsp;&nbsp;<input type="reset" value="重置">
                </td>
            </tr>                    
        </html:form>
</table>
</body>
</html>

-->category_view.jsp
<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ include file="taglibs.jsp"%>
<html>
<head>
    <title>分类新闻</title>
    <link href="styles/news.css" rel="stylesheet" type="text/css">
</head>
<script language="javascript">
    function verifyValue(){
        if(loadNewsForm.newsId.checked)
        {
            loadNewsForm.submit();
            return true;
        }
        for (var i = 0 ; i < loadNewsForm.newsId.length ; i++)
        {
            if( loadNewsForm.newsId[i].checked )
            {
                loadNewsForm.submit();
                return true;
            }
        }
        alert('请选择要查看的新闻!');
        return false;    
    }
    function goMain(){
        mainForm.submit();
    }        
</script>
<body>
    <table width="600" align="center" cellpadding="1" bgcolor="#99CCCC">
        <form name="loadNewsForm" action="loadNewsReviewByNews.do" method="POST"> 
                <tr>
                    <td width="60%" colspan="6" align="center">
                        <p>新闻列表</p>                    </td>
                </tr>
                <tr>
                    <td width="10%" align="center">
                        请选择                    </td>
                    <td width="10%" align="center">
                        主题                    </td>
                    <td width="10%" align="center">
                        发布人                    </td>
                    <td width="10%" align="center">
                        发布时间                    </td>
                    <td width="10%" align="center">
                        最后评论时间                    </td>
                </tr>                
                <logic:iterate id="item" name="news" indexId="index" scope="request">
                    <tr>
                        <td width="10%" align="center">
                            <input type="radio" name="newsId" value='<bean:write name="item" property="id"/>'>
                        </td>
                        <td width="10%" align="center">
                            <bean:write name="item" property="title"/>
                        </td>
                        <td width="10%" align="center">
                            <bean:write name="item" property="content"/>
                        </td>
                        <td width="10%" align="center">
                            <bean:write name="item" property="postDate"/>
                        </td>
                        <td width="10%" align="center">
                            <bean:write name="item" property="lastModifyDate"/>
                        </td>
                    </tr>    
                </logic:iterate>
            <tr>
                <td height="52" colspan="6" align="center">
                    <input type="button" value="查看" onClick="verifyValue();">&nbsp;&nbsp;<input type="reset" value="重置">              </td>
            </tr>
            <tr>
              <td height="25" colspan="6" align="center">&nbsp;</td>
          </tr>
            <tr>
              <td height="25" colspan="6" align="center">发表新的新闻</td>
          </tr>                    
        </form>
        <html:form action="/addNews">
            <tr>
                <td colspan="6" align="center">
                    主题:                </td>
            </tr>
            <tr>    
                <td colspan="6" align="center">
                    <html:text property="title" size="80"/>
                    <input type="hidden" name="categoryId" value='<bean:write name="categoryId"/>'>
                </td>
            </tr>
            <tr>
                <td colspan="6" align="center">
                    内容:                </td>
            </tr>
            <tr>        
                <td colspan="6" align="center">
                    <html:textarea property="content" cols="80" rows="20"></html:textarea>                </td>
            </tr>
            <tr>    
                <td colspan="6" align="center">
                    <input type="submit" value="提交">
                    &nbsp;&nbsp;<input type="reset" value="重置">
                    &nbsp;&nbsp;<input type="button" value="返回" onClick="history.go(-1);">
                    &nbsp;&nbsp;<input type="reset" value="主页" onClick="goMain();">                </td>                
            </tr>
        </html:form>
        <form name="mainForm" action="listCate.do" method="post"">
        </form>        
</table>
</body>
</html>

-->news_view.jsp
<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ include file="taglibs.jsp"%>
<html>
<head>
    <title>新闻详细内容</title>
        <link href="styles/news.css" rel="stylesheet" type="text/css">
</head>
<script language="javascript">
    function verifyValue(){
        if(addNewsReviewForm.content.value == ""){
            alert('请输入评论内容!');
            addNewsReviewForm.content.focus();
            return false;
        }
        addNewsReviewForm.submit();        
    }
    function goMain(){
        mainForm.submit();
    }    
</script>
<body>
<table width="600" align="center" cellpadding="1" bgcolor="#99CCCC">
  <tr>
    <td colspan="2" align="center" bgcolor="#999999"><p>新闻标题:<bean:write name="news" property="title"/></p></td>
  </tr>
   <tr>
    <td width="20%" align="center">新闻内容:</td>
    <td width="80%" align="center" bgcolor="#eeeeee"><bean:write name="news" property="content"/></td>
  </tr>
  <tr>
    <td colspan="2" align="center" bgcolor="#999999">所有评论如下:</td>
  </tr>
  <logic:iterate id="item" name="reviews" indexId="index" scope="request">
  <tr>
    <td colspan="2" bgcolor="#96dede">由网友${item.poster.username}于<bean:write name="item" property="postDate"/>发表的评论如下:</td>
  </tr>
  <tr>
    <td colspan="2" align="center" bgcolor="#ffffff"><bean:write name="item" property="content"/> </td>
  </tr>
  </logic:iterate>
    <html:form action="/addNewsReview">
      <input type="hidden" name="newsId" value='<bean:write name="news" property="id"/>'>
      <tr>
        <td colspan="2" align="center"> 我要评论:      </tr>
      <tr>
        <td colspan="2" align="center"><textarea name="content" cols="80" rows="6"></textarea>        </td>
      </tr>
      <tr>
        <td colspan="2" align="center"><input name="button" type="submit" value="提交">
          &nbsp;&nbsp;
          <input name="reset" type="reset" value="重置">
          &nbsp;&nbsp;
          <input name="button" type="button" onClick="history.go(-1);" value="返回">
          &nbsp;&nbsp;
          <input name="reset" type="reset" onClick="goMain();" value="主页">        </td>
      </tr>
    </html:form>
        <form name="mainForm" action="listCate.do" method="post"">
        </form>
</table>
</body>
</html>