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

 
一、架构
    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();
 *
 * 


 * View Source
 * 


 *
 * 
@author PROLOVE
 
*/

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 " >

            

            
< 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 >
        

        
< 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 = " 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 >     
    

    
< 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 " > @HIBERNATE - DIALECT@ prop >
                

                

            
props >
        
property >
    
bean >

    

    
< bean id = " transactionManager "   class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
        
< property name = " sessionFactory "  ref = " sessionFactory " />
    
bean >

    

    
< bean id = " dao "   class = " org.prolove.dao.hibernate.BaseDAOHibernate " >
        
< property name = " sessionFactory "  ref = " sessionFactory " />
    
bean >

    

    
< bean id = " userDAO "   class = " org.prolove.dao.hibernate.UserDAOHibernate " >
        
< property name = " sessionFactory "  ref = " sessionFactory " />
    
bean >

    

    
< 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 >
    
 
    
< 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 >
    

    
< 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 >     
    

    
< 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 >

    

    
< bean id = " transactionManager "   class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
        
< property name = " sessionFactory "  ref = " sessionFactory " />
    
bean >


    

    
< 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 >

    

    
< 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.
 *
 * 

View Source


 *
 * 
@author Matt Raible
 
*/

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.
 *
 * 


 * View Source
 * 


 *
 * 
@author Matt Raible
 
*/

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.


 *
 * 

View Source


 *
 * 
@author Matt Raible
 
*/

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 >

    

    
< bean id = " daoTemplate "   abstract = " true "  lazy - init = " true " >
        
< property name = " sessionFactory "  ref = " sessionFactory " />
    
bean >

    

    
< bean id = " dao "   class = " org.prolove.dao.hibernate.BaseDAOHibernate "
        parent
= " daoTemplate " />

    

    
< bean id = " userDAO "   class = " org.prolove.dao.hibernate.UserDAOHibernate "
        parent
= " daoTemplate " />

    

    
< bean id = " newsDAO "   class = " org.prolove.dao.hibernate.NewsDAOHibernate "
        parent
= " daoTemplate " />

    

    
< bean id = " newsReviewDAO "   class = " org.prolove.dao.hibernate.NewsReviewDAOHibernate "
        parent
= " daoTemplate " />

    

    
< 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.
 * 
 * 

View Source


 *
 * 
@author Matt Raible
 
*/

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 [email protected]
 * 
@version  1.0
 * 
Copyright (C), 2006-2008, PROLOVE
 * 
This program is protected by copyright laws.
 * 
Program Name:
 * 
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 [email protected]
 * 
@version  1.0
 * 
Copyright (C), 2006-2008, PROLOVE
 * 
This program is protected by copyright laws.
 * 
Program Name:
 * 
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 - 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 - 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 - 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 - 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 >

        

        
< 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 > /*
        

    
        action
        org.apache.struts.action.ActionServlet
        
            config
            /WEB-INF/struts-config.xml
        

        2
    


    
        action
        *.do
    



    
        
            index.jsp
        

        
            /tags/struts-bean
            /WEB-INF/struts-bean.tld
        

        
            /tags/struts-html
            /WEB-INF/struts-html.tld
        

        
            /tags/struts-logic
            /WEB-INF/struts-logic.tld
        

    



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



    版面分类
    


    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();
    }    


    
    
         
                
                    
                        

欢迎,


                    
                
                
                    
                        请选择
                    
                    
                        版面名
                    
                                
                
                    
                        
                            '>
                        
                        
                            
                        
                        
                

            
                
                    
                      
                
                                
        
        
                




-->index.jsp
<%@ page language="java" contentType="text/html;charset=GBK"%>
<%@ include file="taglibs.jsp"%>


    登陆系统
        



       
   
   

       
          

  •    
       

   




    
    

  •     



  •     
        

  •    


  •     
             
                
                    
                        请输入用户名:
                    
                    
                        
                    
                
                
                    
                        请输入密码:
                    
                    
                        
                    
                
                
                    
                          
                    
                                    
            




    -->category_view.jsp
    <%@ page language="java" contentType="text/html;charset=GBK"%>
    <%@ include file="taglibs.jsp"%>


        分类新闻
        


        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();
        }        


        
             
                    
                        
                            

    新闻列表

                        
                    
                    
                        
                            请选择                    
                        
                            主题                    
                        
                            发布人                    
                        
                            发布时间                    
                        
                            最后评论时间                    
                                    
                    
                        
                            
                                '>
                            
                            
                                
                            
                            
                                
                            
                            
                                
                            
                            
                                
                            
                            
                    
                
                    
                                        
                
                
                   
              
                
                  发表新的新闻
                                  
            
            
                
                    
                        主题:                
                
                    
                    
                        
                        '>
                    
                
                
                    
                        内容:                
                
                        
                    
                                        
                
                    
                    
                        
                          
                          
                                                          
                
            
            
                    




    -->news_view.jsp
    <%@ page language="java" contentType="text/html;charset=GBK"%>
    <%@ include file="taglibs.jsp"%>


        新闻详细内容
            


        function verifyValue(){
            if(addNewsReviewForm.content.value == ""){
                alert('请输入评论内容!');
                addNewsReviewForm.content.focus();
                return false;
            }
            addNewsReviewForm.submit();        
        }
        function goMain(){
            mainForm.submit();
        }    



      
        

    新闻标题:


      
       
        新闻内容:
        
      
      
        所有评论如下:
      
      
      
        由网友${item.poster.username}于发表的评论如下:
      
      
         
      
      
        
          '>
          
             我要评论:      
          
                    
          
          
            
                
              
                
              
                
                      
          
        
            
            


    你可能感兴趣的:(J2EE项目:整合SSH开发『新闻发布系统』)