J2EE项目之整合Struts+Hibernate开发电子留言系统

 

 

 

 

 

本电子留言系统采用J2SDK1.5.0_14+Tomcat5.5.25 +MyEclipse5.5.1GA+MySQL5.0.45+Struts1.2.9+Hibernate3.1.2开发。

一、系统架构说明

i.架构说明

虽然本系统没有引入Spring框架,但本项目依然示范了一个优秀的J2EE项目架构,因此,中间层由MVC控制层、业务逻辑组件层、DAO组件层三层组成。系统通过DAO组件进行持久层访问;而用户的请求则只负责与MVC控制器层交互;业务逻辑组件则向上与控制器交互,向下与DAO组件交互

ii.实现自己的DAO层

应用中DAO组件、业务逻辑组件的管理,业务逻辑组件如何定位DAO组件,控制器如何定位业务逻辑组件。

iii.事务的控制

对于一个理想的J2EE应用而言,业务逻辑层不应该出现持久层API。即业务逻辑层组件不再与Hibernate API耦合。抽取所有的事务代码,利用代理模式来为系统中的业务逻辑组件生成事务代理,系统的控制组件则改为依赖于业务逻辑组件的事务代理。

二、系统概要设计

i.确定系统功能

本系统主要包含如下几个最简单但又最基础的基本功能:

用户注册;用户登录;用户留言;用户查看留言

ii.提取用户实体

系统模块划分:MessageManager组件-->UserDao组件-->User持久化对象-->User数据表;MessageManager组件-->MessageDao组件-->Message持久化对象-->Message数据表

三、实现Hibernate持久层

i.Hibernate持久层的POJO

 

package org.prolove.model;

import java.util.Set;
import java.util.HashSet;

public class User
{
    
private int id;
    
private String name;
    
private String pass;

    
private Set<Message> messages = new HashSet<Message>();
    
    
public void setId(int id) {
        
this.id = id; 
    }


    
public void setName(String name) {
        
this.name = name; 
    }


    
public void setPass(String pass) {
        
this.pass = pass; 
    }

    
    
public void setMessages(Set<Message> messages) {
        
this.messages = messages; 
    }
    

    
public int getId() {
        
return (this.id); 
    }


    
public String getName() {
        
return (this.name); 
    }


    
public String getPass() {
        
return (this.pass); 
    }


    
public Set<Message> getMessages(){
        
return (this.messages);
    }

}

 

package org.prolove.model;

public class Message
{
    
private int id;
    
private String title;
    
private String content;

    
private User user;

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


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


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


    
public void setUser(User user) {
        
this.user = user; 
    }


    
public int getId() {
        
return (this.id); 
    }


    
public String getTitle() {
        
return (this.title); 
    }


    
public String getContent() {
        
return (this.content); 
    }


    
public User getUser() {
        
return (this.user); 
    }



}

ii.编写PO的映射配置文件

User.hbm.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<hibernate-mapping package="org.prolove.model">
    
<!-- 每个class元素映射一个持久化类 -->
    
<class name="User" table="user_table">
        
<id name="id">
            
<generator class="identity"/>
        
</id>
        
<property name="name" unique="true"/>
        
<property name="pass"/>
        
<set name="messages"  inverse="true">
            
<key column="owner_id"/>
            
<one-to-many class="Message"/>
        
</set>
    
</class>
</hibernate-mapping>

Message.hbm.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
<hibernate-mapping package="org.prolove.model">
    
<!-- 每个class元素映射一个持久化类 -->
    
<class name="Message" table="message_table">
        
<id name="id">
            
<generator class="identity"/>
        
</id>
        
<property name="title"/>
        
<property name="content"/>
        
<many-to-one name="user" column="owner_id" not-null="true"/>
    
</class>
</hibernate-mapping>

iii.连接数据库

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>

<hibernate-configuration>

    
<session-factory>

        
<!-- Database connection settings -->
        
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        
<property name="connection.url">jdbc:mysql://localhost/message</property>
        
<property name="connection.username">root</property>
        
<property name="connection.password">root</property>

        
<!-- C3P0 connection pool  -->
        
<property name="hibernate.c3p0.max_size">25</property>
        
<property name="hibernate.c3p0.min_size">1</property>
        
<property name="hibernate.c3p0.timeout">5000</property>
        
<property name="hibernate.c3p0.max_statements">100</property>
        
<property name="hibernate.c3p0.idle_test_period">3000</property>
        
<property name="hibernate.c3p0.acquire_increment">2</property>
        
<property name="hibernate.c3p0.validate">true</property>

        
<!-- SQL dialect -->
        
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        
<!-- Echo all executed SQL to stdout -->
        
<property name="show_sql">false</property>

        
<!-- Drop and re-create the database schema on startup -->
        
<property name="hbm2ddl.auto">update</property>

        
<mapping resource="Message.hbm.xml"/>
        
<mapping resource="User.hbm.xml"/>

    
</session-factory>

</hibernate-configuration>

iv.(附加)资源文件

message.properties

# Errors
errors.footer
=出错啦!
errors.header
=<h3><font color="red">出错提示:</font></h3>您必须完成如下提示,才可继续进行:
errors.ioException
=I/O exception rendering error messages: {0}
error.database.missing
=<li>User database is missing, cannot validate logon credentials</li>
errors.required
={0} 必须填写。
errors.minlength
={0} 字符长度必须大于 {1} 个字符。
errors.maxlength
={0} 字符长度必须小于 {1} 字符。
errors.invalid
={0} 无效.

html.li.open
=<li>
html.li.close
=</li>
file.location
=The {0} file for this page can be found in the {1} directory.

errors.byte
={0} 必须是个字节型变量。
errors.short
={0} 必须是个短整型变量。
errors.integer
={0} 必须是个整型变量。
errors.long
={0} 必须是个长整型变量。
errors.float
={0} 必须是个单精度浮点型变量。
errors.double
={0} 必须是个双精度浮点型变量。

errors.date
={0} 必须是个日期。

errors.range
={0} 必须大于{1},并小于{2}。

errors.creditcard
={0} 必须是个有效的信用卡卡号。

errors.email
={0} 必须是个有效的Email地址。
errors.url
={0} 必须是个有效的URL地址。

# Exception
MessageException
=系统业务逻辑异常:{0}

#登陆表单
loginForm.user
=登陆的用户名
loginForm.pass
=登陆的密码

#发表留言表单
postMessageForm.title
=留言标题
postMessageForm.content
=留言内容

#注册表单
registForm.user
=注册的用户名
registForm.pass
=注册的密码

四、DAO组件层

i.DAO模式的结构

DAO接口;DAO实现类;DAO工厂

ii.编写DAO接口

package org.prolove.dao;

import org.prolove.model.*;
import org.hibernate.Session;

import java.util.*;

public interface UserDao
{

    
/**
     * 根据主键加载用户
     * 
@param id 需要加载的用户ID
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@return 加载的用户
     
*/

    User get(Session sess , 
int id);

    
/**
     * 保存用户
     * 
@param u 需要保存的用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@return 保存用户的主键
     
*/

    
int save(Session sess , User u);

    
/**
     * 删除用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param u 需要删除的用户
     
*/

    
void delete(Session sess , User u);

    
/**
     * 删除用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要删除的用户的id
     
*/

    
void delete(Session sess , int id);

    
/**
     * 修改用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param u 需要修改的用户
     
*/

    
void update(Session sess , User u);

    
/**
     * 根据用户名查找用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param name 需要查找的用户的用户名
     * 
@return 查找到的用户
     
*/

    User findByName(Session sess , String name);
}

 

package org.prolove.dao;

import org.prolove.model.*;
import org.hibernate.Session;


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

public interface MessageDao
{
    
/**
     * 根据主键加载消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要加载的消息ID
     * 
@return 加载的消息
     
*/

    Message get(Session sess , 
int id);

    
/**
     * 保存消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要保存的消息
     * @retun 保存消息的主键
     
*/

    
int save(Session sess , Message m);

    
/**
     * 删除消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要删除的消息
     
*/

    
void delete(Session sess , Message m);

    
/**
     * 删除消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要删除的消息ID
     
*/

    
void delete(Session sess , int id);

    
/**
     * 修改消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要修改的消息
     
*/

    
void update(Session sess , Message m);

    
/**
     * 查询指定用户、指定页的消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param pageNo 需要查询的指定页
     * 
@return 查询到的消息集合
     
*/

    List findAllByPage(Session sess , 
int pageNo , int pageSize);

    
/**
     * 查询消息的条数
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@return 消息条数
     
*/

    
long findCount(Session sess);
}

iii.实现DAO组件

Step:1.获取Hibernate Session;2.进行持久化操作;3.关闭Hibernate Session

package org.prolove.dao.impl;

import org.prolove.model.*;
import org.prolove.dao.*;
import org.hibernate.Session;

import java.util.*;
import java.io.Serializable;

public class UserDaoHibernate implements UserDao
{

    
/**
     * 根据主键加载用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要加载的用户ID
     * 
@return 加载的用户
     
*/

    
public User get(Session sess, int id)
    
{
        
return (User)sess.load(User.class , id);
    }


    
/**
     * 保存用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param u 需要保存的用户
     * 
@return 保存用户的主键
     
*/

    
public int save(Session sess, User u)
    
{
        sess.save(u);
        
return u.getId();
    }


    
/**
     * 删除用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param u 需要删除的用户
     
*/

    
public void delete(Session sess, User u)
    
{
        sess.delete(u);
    }


    
/**
     * 删除用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要删除的用户的id
     
*/

    
public void delete(Session sess, int id)
    
{
        sess.delete(get(sess, id));
    }


    
/**
     * 修改用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param u 需要修改的用户
     
*/

    
public void update(Session sess, User u)
    
{
        sess.saveOrUpdate(u);
    }


    
/**
     * 根据用户名查找用户
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param name 需要查找的用户的用户名
     * 
@return 查找到的用户
     
*/

    
public User findByName(Session sess, String name)
    
{
        List ul 
= sess.createQuery("from User as u where u.name = ?")
            .setParameter(
0 , name)
            .list();
        
if (ul != null && ul.size() > 0)
        
{
            
return (User)ul.get(0);
        }

        
return null;
    }

}
 

 

package org.prolove.dao.impl;

import org.prolove.model.*;
import org.prolove.dao.*;
import org.hibernate.Session;


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

public class MessageDaoHibernate implements MessageDao
{

    
/**
     * 根据主键加载消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要加载的消息ID
     * 
@return 加载的消息
     
*/

    
public Message get(Session sess, int id)
    
{
        
return (Message)sess.load(Message.class , id);
    }


    
/**
     * 保存消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要保存的消息
     * @retun 保存消息的主键
     
*/

    
public int save(Session sess, Message m)
    
{
        sess.save(m);
        
return m.getId();
    }


    
/**
     * 删除消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要删除的消息
     
*/

    
public void delete(Session sess, Message m)
    
{
        sess.delete(m);
    }


    
/**
     * 删除消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param id 需要删除的消息ID
     
*/

    
public void delete(Session sess, int id)
    
{
        sess.delete(get(sess , id));
    }


    
/**
     * 修改消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param m 需要修改的消息
     
*/

    
public void update(Session sess, Message m)
    
{
        sess.saveOrUpdate(m);
    }


    
/**
     * 查询指定用户、指定页的消息
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@param pageNo 需要查询的指定页
     * 
@param pageSize 每页显示的消息数
     * 
@return 查询到的消息集合
     
*/

    
public List findAllByPage(Session sess, int pageNo , int pageSize)
    
{
        
int offset = (pageNo - 1* pageSize;
        
return sess.createQuery("from Message m order by m.id desc")
            .setFirstResult(offset)
            .setMaxResults(pageSize)
            .list();
    }


    
/**
     * 查询消息的条数
     * 
@param sess 持久化操作所需要的Hiberate Session
     * 
@return 消息条数
     
*/

    
public long findCount(Session sess)
    
{
        Object obj 
= sess.createQuery("select count(m.id) from Message as m")
            .uniqueResult();
        
//System.out.println(obj);
        return (Long)obj;
    }

}

iv.实现DAO工厂

配置文件-->daoContext.xml

 

 

<?xml version="1.0" encoding="GBK"?>
<daoContext>
    
<dao id="userDao" class="org.prolove.dao.impl.UserDaoHibernate"/>
    
<dao id="messageDao" class="org.prolove.dao.impl.MessageDaoHibernate"/>
</daoContext>

 

package org.prolove.factory;

import org.prolove.dao.*;
import org.prolove.dao.impl.*;

import org.dom4j.*;
import org.dom4j.io.*;

import java.util.*;
import java.io.*;

public class DaoFactory
{
    
private Map<String , Object> daoMap = new HashMap<String , Object>(); 

    
private static DaoFactory df;
    
    
private DaoFactory(String path)throws Exception
    
{
        Document doc 
= new SAXReader().read(new File(path + "/daoContext.xml"));
        Element root 
= doc.getRootElement();
        List el 
=  root.elements();
        
for (Iterator it = el.iterator();it.hasNext() ; )
        
{
            Element em 
= (Element)it.next();
            String id 
= em.attributeValue("id");
            String impl 
= em.attributeValue("class");
            Class implClazz 
= Class.forName(impl);
            Object obj 
= implClazz.newInstance();
            daoMap.put(id , obj);            
        }

    }


    
public static DaoFactory instance(String path)throws Exception
    
{
        
if (df == null)
        
{
            df 
= new DaoFactory(path); 
        }

        
return df;
    }


    
public Object getDao(String id)
    
{
        
return daoMap.get(id);
    }

}

五、业务逻辑层

i.业务逻辑组件的接口

package org.prolove.service;

import org.prolove.exception.*;
import org.prolove.vo.*;

import java.util.List;
import javax.servlet.http.HttpServletRequest;

public interface MessageManager 
{
    
int MESSAGE_PAGE_SIZE = 3;
    
/**
     * 创建一条消息
     * 
@param title 新信息的标题
     * 
@param content 新消息的内容
     * 
@param userId 创建消息的用户Id
     * 
@return 新创建消息的主键,如果创建失败,返回-1。
     
*/

    
int createMessage(String title , String content , int userId)
        
throws MessageException;

    
/**
     * 创建一个用户
     * 
@param user 新创建用户的用户名
     * 
@param pass 新创建用户的密码
     * 
@return 新创建用户的主键
     
*/

    
int createUser(String user , String pass)
        
throws MessageException;

    
/**
     * 验证用户名是否可用,本系统不允许用户名重复
     * 
@param user 需要验证的用户名
     * 
@return 该用户名不重复,可用,返回true,否则返回false
     
*/

    
boolean valid(String user)
        
throws MessageException;

    
/**
     * 验证用户登录是否成功
     * 
@param user 登录所用的用户名
     * 
@param pass 登录所用的密码
     * 
@param session 登录后需将用户名存入session
     * 
@return 登录成功,返回用户的id,否则返回-1.
     
*/

    
int login(String user , String pass)
        
throws MessageException;

    
/**
     * 根据消息ID返回消息
     * 
@param id 消息ID
     * 
@return 指定ID对应的消息
     
*/

    MessageBean getMessage(
int id)
        
throws MessageException;

    
/**
     * 返回特定页面所有消息
     * 
@param pageNo 指定页码
     * 
@return 指定页的全部消息
     
*/

    List
<MessageBean> getAllMessageByPage(int pageNo)
        
throws MessageException;

    
/**
     * 获取消息数量
     * 
@return 消息的数量
     
*/

    
int getMessageCount()throws MessageException;
    
    
/**
     * 根据每页记录数,总记录数获取总页数
     * 
@param count 总记录数
     * 
@param pageSize 每页显示的记录数
     * 
@return 计算得到的总页数
     
*/

    
int getPageCount(int count , int pageSize);

}

ii.控制事务

本系统采用在业务逻辑方法中手动控制事务。

iii.实现业务逻辑组件

iv.业务逻辑组件与控制器的耦合

package org.prolove.action.base;


import org.prolove.service.MessageManager;
import org.prolove.service.impl.MessageManagerImpl;

import org.apache.struts.action.Action;

public class BaseAction extends Action
{
    
protected static MessageManager messManager;
    
    
static 
    
{
        
try
        
{
            messManager 
= new MessageManagerImpl();
        }

        
catch (Exception e)
        
{
            e.printStackTrace();
        }

    }


}

六、Web层设计

此处的Web层指的是系统中间层以上的部分,包括系统控制层以及对应的JSP页面。

i.实现系统的Listener

 

 

 

 

package org.prolove.web;

import javax.servlet.*;
import org.prolove.factory.*;
import org.hibernate.SessionFactory;

public class FactoryLoaderListener implements ServletContextListener

    DaoFactory df 
= null;
    SessionFactory sf 
= null;
    
public void contextInitialized(ServletContextEvent sce)
    
{
        
try
        
{
            sf 
= SessionFactoryBuilder.instance().getSessionFactory();
            System.out.println(
"Hibernate的SessionFactory已经被初始化... " + sf);    
        }

        
catch (Exception e)
        
{
            System.out.println(
"初始化SessionFactory工厂时出现异常" + e);
        }

        
try
        
{
            String path 
= sce.getServletContext().getRealPath("/WEB-INF/");
            df 
= DaoFactory.instance(path);
            System.out.println(
"DAO工厂已经被初始化... " + df);

        }

        
catch (Exception e)
        
{
            System.out.println(
"初始化DAO工厂时出现异常" + e);
        }

    }
 
    
    
public void contextDestroyed(ServletContextEvent sce)
    
{
        sf 
= null;
        df 
= null;
    }
 
}
 

ii.使用Struts拦截所有请求

package org.prolove.action.base;

import org.apache.struts.action.ActionServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  
public class MyActionServlet extends org.apache.struts.action.ActionServlet
{
    
protected void process(HttpServletRequest request, HttpServletResponse response)
        
throws java.io.IOException, javax.servlet.ServletException
    
{
        request.setCharacterEncoding(
"GBK");
        
super.process(request, response);
    }

}

配置-->web.xml

 

 

 

 

 

<?xml version="1.0" encoding="GBK"?>
<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>loginFilter</filter-name>
        
<filter-class>org.prolove.web.UserLoginFilter</filter-class>
        
<init-param>
            
<param-name>forwardpath</param-name>
            
<param-value>/index.jsp</param-value>
        
</init-param>
    
</filter>
    
<filter-mapping>
        
<filter-name>loginFilter</filter-name>
        
<url-pattern>/*</url-pattern>
    
</filter-mapping>

    
<listener> 
        
<listener-class>org.prolove.web.FactoryLoaderListener</listener-class> 
    
</listener> 

    
<servlet>
        
<servlet-name>action</servlet-name>
        
<servlet-class>org.prolove.action.base.MyActionServlet</servlet-class>
        
<load-on-startup>1</load-on-startup>
    
</servlet>
    
<servlet-mapping>
        
<servlet-name>action</servlet-name>
        
<url-pattern>*.do</url-pattern>
    
</servlet-mapping>

</web-app>

iii.完成用户登录

package org.prolove.action;

import org.apache.struts.action.*;
import org.apache.struts.validator.DynaValidatorForm;
import javax.servlet.http.*;

import org.prolove.action.base.BaseAction;
import static org.prolove.util.AppConstants.*;

public class ProcessLoginAction extends BaseAction
{
    
public ActionForward execute(ActionMapping mapping,ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
throws Exception
    
{
        DynaValidatorForm loginForm 
= (DynaValidatorForm)form;
        String user 
= (String)loginForm.get("user");
        String pass 
= (String)loginForm.get("pass");
        
int userId = messManager.login(user , pass);
        
if (userId > 0)
        
{
            request.getSession().setAttribute(LOGIN_USER , userId);
            
return mapping.findForward("success");
        }

        request.setAttribute(
"msg" , "用户名和密码不匹配,请重试");
        
return mapping.findForward("failure");
    
    }

}

统一给出配置文件: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="postMessageForm" type="org.apache.struts.validator.DynaValidatorForm">
              
<form-property name="title" type="java.lang.String"/>
              
<form-property name="content" type="java.lang.String"/>
        
</form-bean>

        
<form-bean name="registForm" 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-beans>   


    
<global-exceptions>
            
<exception key="MessageException"  
                       type
="org.yeeku.exception.MessageException"
                       scope
="request"
                       path
="/WEB-INF/jsp/error.jsp"/>    
    
</global-exceptions>

    
<action-mappings>
        
<action path="/enterPostMessage" forward="/WEB-INF/jsp/postMessage.jsp"/>
        
<action path="/enterRegist" forward="/WEB-INF/jsp/regist.jsp"/>


        
<!-- 处理用户登录 -->
        
<action path="/processLogin" name="loginForm" type="org.prolove.action.ProcessLoginAction"
            scope
="request" validate="true" input="/WEB-INF/jsp/login.jsp">
            
<forward name="success" path="/listMessage.do" />
            
<forward name="failure" path="/WEB-INF/jsp/login.jsp" />
        
</action>
        
<!-- 处理用户注册 -->
        
<action path="/processRegist" name="registForm" type="org.prolove.action.ProcessRegistAction"
            scope
="request" validate="true" input="/WEB-INF/jsp/login.jsp">
            
<forward name="success" path="/WEB-INF/jsp/login.jsp" />
            
<forward name="failure" path="/WEB-INF/jsp/regist.jsp" />

        
</action>

        
<!-- 列出所有消息 -->
        
<action path="/listMessage"  type="org.prolove.action.ListMessageAction"
            scope
="request">
            
<forward name="success" path="/WEB-INF/jsp/listMessage.jsp" />
        
</action>

        
<!-- 处理添加消息 -->
        
<action path="/processPostMessage" name="postMessageForm" type="org.prolove.action.ProcessPostMessageAction"
            scope
="request" validate="true" input="/WEB-INF/jsp/postMessage.jsp">
            
<forward name="success" path="/listMessage.do" />
        
</action>

        
<!-- 处理查看消息 -->
        
<action path="/viewMessage" type="org.prolove.action.ViewMessageAction"
            scope
="request">
            
<forward name="success" path="/WEB-INF/jsp/viewMessage.jsp" />
        
</action>

    
</action-mappings>

    
<message-resources  parameter="message"/>

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

</struts-config>

iv.列出留言列表

package org.prolove.action;

import org.apache.struts.action.*;
import org.apache.struts.validator.DynaValidatorForm;
import javax.servlet.http.*;

import org.prolove.service.MessageManager;
import org.prolove.action.base.BaseAction;

public class ListMessageAction extends BaseAction
{
    
public ActionForward execute(ActionMapping mapping,ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
throws Exception
    
{
        
int messageCount = messManager.getMessageCount();

        
//获取总页数
        int pageCount = messManager.getPageCount(messageCount , MessageManager.MESSAGE_PAGE_SIZE);

        
int pageNo;
        String pageNoStr 
= request.getParameter("pageNo");
        
if (pageNoStr == null || pageNoStr.trim().equals(""))
        
{
            pageNo 
= 1;
        }

        
try
        
{
            pageNo 
= Integer.parseInt(pageNoStr.trim());
        }

        
catch (Exception e)
        
{
            pageNo 
= 1;
        }

        
//如果请求页已经超出了最大页
        if (pageNo > pageCount)
        
{
            pageNo 
= pageCount;
        }

        request.setAttribute(
"pageCount" , pageCount);
        request.setAttribute(
"currentPage" , pageNo);
        request.setAttribute(
"messageList" , messManager.getAllMessageByPage(pageNo));
        
return mapping.findForward("success");

    
    }

}

JSP页面中输出Request中List属性-->listMessage.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="exception.jsp"%>
<%@include file="taglibs.jsp"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>列出所有留言</title>
<link href="img/css.css" rel="stylesheet" type="text/css">

</head>

<body>
<div align="center">
<div class="dojoDialog" style="width:600px;">
<table border="1" align="center" width="600" style="border-collapse:collapse;font-size:10pt" >
  
<caption>
    电子留言系统
  
</caption>
  
<tr>
    
<td colspan="2" align="right"><href="enterPostMessage.do"> 发表新留言</a></td>
  
</tr>
  
<tr>
    
<th width="120">作者</th>
    
<th width="480" >留言标题</th>
  
</tr>
<logic:present name="messageList" scope="request" >
<logic:iterate id="message" name="messageList" type="org.yeeku.vo.MessageBean" scope="request" >
    
<tr>
      
<td align="center" width="167"><bean:write name="message" property="owerName"/></td>
      
<td align="center"><href='viewMessage.do?messageId=<bean:write name="message" property="id"/>'><bean:write name="message" property="title"/></a></td>
    
</tr>
</logic:iterate>
  
<tr>
    
<td align="right" colspan="2">
        第${requestScope.currentPage}页
&nbsp;
        共${requestScope.pageCount}页
&nbsp;
        
<href="listMessage.do?pageNo=1">首页</a>
        
<logic:greaterThan name="currentPage" value="1" scope="request"><href="listMessage.do?pageNo=${requestScope.currentPage - 1}"></logic:greaterThan>
        上一页
        
<logic:greaterThan name="currentPage" value="1" scope="request"></a></logic:greaterThan>
        
<logic:lessThan name="currentPage" value='${requestScope.pageCount}' scope="request"><href="listMessage.do?pageNo=${requestScope.currentPage + 1}"></logic:lessThan>
        下一页
<logic:lessThan name="currentPage" value='${requestScope.pageCount}' scope="request"></a></logic:lessThan>
        
<href="listMessage.do?pageNo=${requestScope.pageCount}">尾页</a>
  
</td>
  
</tr>
</logic:present>
<logic:notPresent name="messageList" scope="request" >
  
<tr>
    
<td align="center" colspan="2">暂时没有任何留言</td>
  
</tr>
</logic:notPresent>
</table>
</div>
</div>
 
<%@include file="copyright.jsp"%>
</body>
</html>

v.查看留言

package org.prolove.action;

import org.apache.struts.action.*;
import org.apache.struts.validator.DynaValidatorForm;
import javax.servlet.http.*;

import org.prolove.service.MessageManager;
import org.prolove.action.base.BaseAction;
import org.prolove.exception.MessageException;

public class ViewMessageAction extends BaseAction
{
    
public ActionForward execute(ActionMapping mapping,ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
throws Exception
    
{
        String idStr 
= request.getParameter("messageId");
        
int messageId = 0;
        
if (idStr == null || idStr.trim().equals(""))
        
{
            
throw new MessageException(" 需要查看的留言ID丢失");
        }

        
try
        
{
            messageId 
= Integer.parseInt(idStr.trim());
        }

        
catch (Exception e)
        
{
            
throw new MessageException("非法的留言ID");
        }

        request.setAttribute(
"viewing" , messManager.getMessage(messageId));
        
return mapping.findForward("success");

    
    }

}

 

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="exception.jsp"%><%@include file="taglibs.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>查看留言</title>
<link href="img/css.css" rel="stylesheet" type="text/css">
</head>
<body>
<div align="center">
<div class="dojoDialog" style="width:600px;">
    
<table>
        
<caption>查看留言</caption>
            
<tr>
                
<td>标题:</td>
                
<td>${requestScope.viewing.title}</td>
            
</tr>
            
<tr>
                
<td>发布者:</td>
                
<td>${requestScope.viewing.owerName}</td>
            
</tr>
            
<tr>
                
<td>内容:</td>
                
<td><textarea cols="50" rows="8" disabled>${requestScope.viewing.content}</textarea></td>
            
</tr>
            
<tr>
                
<td colspan="2" align="center">
                    
<href="listMessage.do">返回</a>
                
</td>
            
</tr>
    
</table>
</div>
</div>
 
<%@include file="copyright.jsp"%>
</body>
</html>

vi.数据校验的处理

-->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>3</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>3</var-value>
                
</var>
            
</field>
        
</form>

        
<form name="postMessageForm">
            
<field property="title" depends="required,minlength">
                
<arg key="postMessageForm.title" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>3</var-value>
                
</var>
            
</field>
            
<field property="content" depends="required,minlength">
                
<arg key="postMessageForm.content" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>10</var-value>
                
</var>
            
</field>
        
</form>

        
<form name="registForm">
            
<field property="user" depends="required,minlength">
                
<arg key="registForm.title" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>3</var-value>
                
</var>
            
</field>
            
<field property="pass" depends="required,minlength">
                
<arg key="registForm.content" position="0"/>
                
<arg name="minlength" key="${var:minlength}" resource="false" position="1"/>
                
<var>
                    
<var-name>minlength</var-name>
                    
<var-value>3</var-value>
                
</var>
            
</field>
        
</form>

    
</formset>
</form-validation>

vii.权限管理

package org.prolove.web;

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 static org.prolove.util.AppConstants.*;

/**
 * 过滤未登录的非法请求
 
*/

public class UserLoginFilter implements Filter
{

    
private String forwardPath = null;
    
private FilterConfig filterConfig = null;

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


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

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

        chain.doFilter(request, response);
    }


    
public void init(FilterConfig filterConfig) throws ServletException
    
{
        
this.filterConfig = filterConfig;
        
this.forwardPath = filterConfig.getInitParameter("forwardpath");
    }

}

 

package org.prolove.util;

public interface AppConstants
{
    String LOGIN_USER 
= "user";
}

 

 

 

package org.prolove.service.impl;

import org.prolove.dao.*;
import org.prolove.model.*;
import org.prolove.exception.*;
import org.prolove.service.*;
import org.prolove.vo.*;
import org.prolove.factory.*;

import java.util.List;
import java.util.ArrayList;
import org.hibernate.*;

public class MessageManagerImpl implements MessageManager
{
    
private UserDao userDao;
    
private MessageDao messDao;

    
public MessageManagerImpl()throws MessageException
    
{
        
try
        
{
            userDao 
= (UserDao)DaoFactory.instance(null).getDao("userDao");
            messDao 
= (MessageDao)DaoFactory.instance(null).getDao("messageDao");            
        }

        
catch (Exception e)
        
{
            e.printStackTrace();
            
throw new MessageException("初始化业务逻辑组件出现异常...");
        }


    }



    
/**
     * 创建一条消息
     * 
@param title 新信息的标题
     * 
@param content 新消息的内容
     * 
@param userId 创建消息的用户Id
     * 
@return 新创建消息的主键,如果创建失败,返回-1。
     
*/

    
public int createMessage(String title , String content , int userId)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();
            User u 
= userDao.get(sess , userId);
            
if ( u != null)
            
{
                Message m 
= new Message();
                m.setTitle(title);
                m.setContent(content);
                m.setUser(u);
                messDao.save(sess , m);
                tx.commit();
                
return m.getId();
            }

            tx.commit();
            
return -1;
        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("添加消息出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 创建一个用户
     * 
@param user 新创建用户的用户名
     * 
@param pass 新创建用户的密码
     * 
@return 新创建用户的主键
     
*/

    
public int createUser(String user , String pass)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();

            
if (userDao.findByName(sess , user) != null)
                
throw new MessageException("该用户名已经存在");
            User u 
= new User();
            u.setName(user);
            u.setPass(pass);
            userDao.save(sess, u);
            tx.commit();
            
return u.getId();
        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("注册用户出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 验证用户名是否可用,本系统不允许用户名重复
     * 
@param user 需要验证的用户名
     * 
@return 该用户名不重复,可用,返回true,否则返回false
     
*/

    
public boolean valid(String user)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();
            
if (userDao.findByName(sess, user) == null)
            
{
                tx.commit();
                
return true;
            }

            tx.commit();
            
return false;
        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("验证用户名出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 验证用户登录是否成功
     * 
@param user 登录所用的用户名
     * 
@param pass 登录所用的密码
     * 
@return 登录成功,返回用户的id,否则返回-1.
     
*/

    
public int login(String user , String pass)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();
            User u 
= userDao.findByName(sess , user);
            
if (u != null && u.getPass().equals(pass))
            
{
                tx.commit();
                
return u.getId();
            }

            tx.commit();
            
return -1;

        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("处理登录出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }



    
/**
     * 根据消息ID返回消息
     * 
@param id 消息ID
     * 
@return 指定ID对应的消息
     
*/

    
public MessageBean getMessage(int id)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();
            Message m 
= messDao.get(sess , id);
            
if (m != null)
            
{
                tx.commit();
                
return new MessageBean(0 , m.getTitle() , m.getContent() , m.getUser().getId() , m.getUser().getName());
            }

            tx.commit();
            
return null;

        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("获取消息内容出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 返回特定页面所有消息
     * 
@param pageNo 指定页码
     * 
@return 指定页的全部消息
     
*/

    
public List<MessageBean> getAllMessageByPage(int pageNo)
        
throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();

            List ml 
= messDao.findAllByPage(sess , pageNo , MESSAGE_PAGE_SIZE);
            
if (ml != null && ml.size() > 0)
            
{
                List
<MessageBean> result = new ArrayList<MessageBean>();
                
for (Object obj : ml)
                
{
                    Message me 
= (Message)obj;
                    result.add(
new MessageBean(me.getId() , me.getTitle(), null , 0 , me.getUser().getName()));
                }

                tx.commit();
                
return result;
            }

            tx.commit();
            
return null;
        }

        
catch (Exception e)
        
{
            tx.rollback();
            e.printStackTrace();
            
throw new MessageException("获取消息内容出现异常");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 获取消息数量
     * 
@return 消息的数量
     
*/

    
public int getMessageCount()throws MessageException
    
{
        Session sess 
= null;
        Transaction tx 
= null;
        
try
        
{
            sess 
= SessionFactoryBuilder.instance().getSessionFactory().openSession();
            tx 
= sess.beginTransaction();
            
int result = (int)messDao.findCount(sess);
            tx.commit();
            
return result;
        }

        
catch (Exception e)
        
{
            tx.rollback();
            
throw new MessageException("获取试题数量时出现异常,请重试!");
        }

        
finally
        
{
            sess.close();
        }

    }


    
/**
     * 根据每页记录数,总记录数获取总页数
     * 
@param count 总记录数
     * 
@param pageSize 每页显示的记录数
     * 
@return 计算得到的总页数
     
*/

    
public int getPageCount(int count , int pageSize)
    
{
        
return (count + pageSize - 1 ) / pageSize;
    }

}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值