本电子留言系统采用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
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);
}
}
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
<! 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
<! 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
<! 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.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接口
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);
}
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
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;
}
}
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
< daoContext >
< dao id ="userDao" class ="org.prolove.dao.impl.UserDaoHibernate" />
< dao id ="messageDao" class ="org.prolove.dao.impl.MessageDaoHibernate" />
</ daoContext >
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.业务逻辑组件的接口
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.业务逻辑组件与控制器的耦合
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
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拦截所有请求
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
< 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.完成用户登录
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
<! 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.列出留言列表
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
<% ... @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.查看留言
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");
}
}
<! 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
<! 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.权限管理
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");
}
}
public interface AppConstants
... {
String LOGIN_USER = "user";
}
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;
}
}