本电子留言系统采用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"><a 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"><a 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}页
共${requestScope.pageCount}页
<a href="listMessage.do?pageNo=1">首页</a>
<logic:greaterThan name="currentPage" value="1" scope="request"><a 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"><a href="listMessage.do?pageNo=${requestScope.currentPage + 1}"></logic:lessThan>
下一页<logic:lessThan name="currentPage" value='${requestScope.pageCount}' scope="request"></a></logic:lessThan>
<a 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">
<a 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;
}
}

9377

被折叠的 条评论
为什么被折叠?



