BBS之二

  
上次只发了一半,今天接着上次的内容发给大家来看,呵呵希望会有所帮助。
 
l        构建 Ibatis 的配置文件和映射文件 ( 详细讲解请参考 ibatis 开发指南 )
(1)    配置文件 代码如下:
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <settings cacheModelsEnabled="true" enhancementEnabled="true"
           lazyLoadingEnabled="true" maxRequests="32" maxSessions="10"
           maxTransactions="5" useStatementNamespaces="false" />
    <typeAlias alias="user" type="com.sample.domain.User" />
    <typeAlias alias="article" type="com.sample.domain.Article" />
    <transactionManager type="JDBC">
           <dataSource type="SIMPLE">
                  <property name="JDBC.Driver" value="com.mysql.jdbc.Driver" />
                  <property name="JDBC.ConnectionURL"
                         value="jdbc:mysql://localhost:3306/sample" />
                  <property name="JDBC.Username" value="root" />
                  <property name="JDBC.Password" value="root" />
           </dataSource>
    </transactionManager>      
    <sqlMap resource="com/sample/dao/impl/User.xml" />
    <sqlMap resource="com/sample/dao/impl/Article.xml" />
</sqlMapConfig>
(2)    SQL Map 映射文件
User.xml 文件代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
                      "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
<insert id="addUser" parameterClass="user">
<!-- sql 语句放在 cdata 段里,避免因特殊字符出现而遇到问题  -->
        <![CDATA[
               insert into user (logon_name, nick_name, password) values (#logonName#, #nickName#, #password#)
        ]]>
        <selectKey keyProperty="id">
               select last_insert_id()
        </selectKey>
</insert>
<select id="getUserById" resultClass="user" parameterClass="int">
        <![CDATA[
               select
                      id as id,
                      logon_name as logonName,
                      nick_name as nickName,
                      password as password
               from user where id=#val#
        ]]>
</select>
<select id="getUserByLogonName" resultClass="user" parameterClass="string">
        <![CDATA[
               select
                      id as id,
                      logon_name as logonName,
                      nick_name as nickName,
                      password as password
               from user where logon_name=#val#
        ]]>
</select>
<select id="getUserByLogonNameAndPassword" resultClass="user" parameterClass="user">
        <![CDATA[
               select
                      id as id,
                      logon_name as logonName,
                      nick_name as nickName,
                      password as password
                      from user where logon_name=#logonName# and password=#password#
        ]]>
</select>
</sqlMap>
Article.xml User.xml 不能具有同名的 id 如果有的话需要设置名称空间。
Article.xml 配置类似 User.xml 代码略。
l        ArticleServiceTest
该类也是一个 junit 测试类,用来测试对帖子的增、删、改、查的各个方法。代码如下:
public class ArticleServiceTest extends TestCase {
ArticleService articleService;
UserService userService;
public ArticleServiceTest(String arg0) {
        super(arg0);
        articleService = new ArticleServiceImpl(new ArticleDaoIbatisImpl());
        userService = new UserServiceImpl(new UserDaoIbatisImpl());
}
   /**
    * 此方法模拟用户注册 -> 发贴的流程。帖子内容在方法内部使用硬编码产生。
     * @param post 帖子后缀(防止出现重复)
     * @param parentid 如果是跟贴,则设置所属主贴的 id
     * @return 发出的帖子( Article 的对象)
     */
private Article addArticle(String post, int parentId) {
    // 生成一个新的用户
        User user = new User();
        user.setLogonName("logonName1" + post);
        user.setNickName("nickName1" + post);
        user.setPassword("password" + post);
        // 注册该用户
        this.userService.regist(user);
     /** 生成一篇新的文章,
       * 并设置标题、内容、所属主贴、发贴日期
       * 将新注册的用户设为发帖人
       */
        Article art = new Article();
        art.setTitle("title" + post);
        art.setContent("content" + post);
        art.setParentId(parentId);
        art.setIssue(new Date());
        art.setAuthor(user);
        this.articleService.addArticle(art);
        return art;
}
 // 测试添加发贴是否成功
public void testAddArticle() {
        Article art = this.addArticle("1", 0);
        assertTrue(art.getId() > 0);
}
public void testGetArticleById() {
        Article art = this.addArticle("2", 0);
        Article a = this.articleService.getArticleById(art.getId());
        assertEquals(art.getTitle(), a.getTitle());
}
 // 测试删除帖子的方法
public void testDelArticle() {
        Article art = this.addArticle("3", 0);
        this.articleService.delArticle(art.getId(), art.getAuthor());
        Article a = this.articleService.getArticleById(art.getId());
        assertNull(a);
}
public void testUpdateArticle() {
        Article art = this.addArticle("4", 0);
        art.setTitle("new title");
        art.setContent("new content");
        this.articleService.updateArticle(art, art.getAuthor());
        Article a = this.articleService.getArticleById(art.getId());
        assertEquals(art.getTitle(), a.getTitle());
        assertEquals(art.getContent(), a.getContent());
}
 // 测试跟贴
public void testGetChildrenArticles() {
        Article art = this.addArticle("5", 0);
        this.addArticle("6", art.getId());
        this.addArticle("7", art.getId());
        this.addArticle("8", art.getId());
        List<Article> arts = this.articleService.getChildrenArticles(art
                      .getId());
        assertEquals(3, arts.size());
}
}
小型BBS
上次主要是针对业务逻辑层和数据访问层,以下主要就是设计和实现 WEB 层(采用 Struts 框架)
1. Struts 的优缺点
缺点:它与 formbean 以及 jsp 绑定太紧密了。
                  它的标签比较复杂。
优点:它是最简单的 MVC 设计模式,而且文档比较全。这也是它比 WebWork 应用更广泛的原因之一。
2.      Struts 环境的搭建
导入必须的 jar
3.      WEB 层的开发
l        配置文件
struts-config.xml 是整个 Struts 的核心。代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!--    <global-exceptions>
        <exception key="expired.password"
                   type="cn.pf.tbbs.exception.DataAccessException"
                   path="/WEB-INF/jsp/comm/DataAccessException.jsp">
        </exception>
        <exception key="expired.password"
                   type="cn.pf.tbbs.exception.ServiceException"
                   path="/WEB-INF/jsp/comm/ServiceException.jsp">
        </exception>
        <exception key="expired.password"
                   type="java.lang.Exception"
                   path="/WEB-INF/jsp/comm/UnknownException.jsp">
        </exception>
    </global-exceptions>-->
    <action-mappings>
        <action path="/home"
                type="cn.pf.tbbs.actions.HomeAction"
                input="/index.jsp">
            <forward name="home" path="/WEB-INF/jsp/home.jsp"/>
        </action>
        <action path="/user/User"
                type="cn.pf.tbbs.actions.UserAction"
                parameter="m"
                input="/WEB-INF/jsp/home.jsp">
            <forward name="regist" path="/WEB-INF/jsp/user/Regist.jsp"/>
            <forward name="info" path="/WEB-INF/jsp/user/Info.jsp"/>
            <forward name="logon" path="/WEB-INF/jsp/user/Logon.jsp"/>
        </action>
        <action path="/article/Article" type="cn.pf.tbbs.actions.ArticleAction"
                parameter="m">
          <forward name="showlist" path="/WEB-INF/jsp/article/topiclist.jsp"/>
          <forward name="showpost" path="/WEB-INF/jsp/article/showpost.jsp"/>
           <forward name="articleForm" path="/WEB-INF/jsp/article/ArticleForm.jsp"/>
        </action>
    </action-mappings>
    <message-resources parameter="MessageResources"/>
</struts-config>
l        InitServlet 
       该类是一个初始化的 Servlet ,它负责把业务层和数据层的实现类存放到 ServletContext 容器环境中去,以便 WEB 层的调用。在写该类之前需要在 web.xml 文件中注册,并把业务层和数据层的实现类存放到该 servlet 的初始化参数中,以便告诉 servlet 我们的 userdao 是什么样的实现类。这样做还有一个好处就是参数只对该 servlet 可见。 InitServlet 的代码如下:
public class InitServlet implements Servlet {
       private ServletConfig config;
       public void destroy() {
              System.out.println("InitServlet destroy...");
       }
       public ServletConfig getServletConfig() {
              return this.config;
       }
       public String getServletInfo() {
              return"init servlet";
       }
       public void init(ServletConfig config) throws ServletException {
              this.config = config;
              try {
                     Object userDao = Class.forName(
                                   config.getInitParameter("userDaoClassName")).newInstance();
                     Class userServiceClass = Class.forName(config
                                   .getInitParameter("userServiceClassName"));
                     Constructor con = userServiceClass
                                   .getConstructor(new Class[] { UserDao.class });
                     Object userService = con.newInstance(new Object[] { userDao });
                     config.getServletContext().setAttribute(
                                   UserService.class.getName(), userService);
                     Object articleDao = Class.forName(
                                   config.getInitParameter("articleDaoClassName"))
                                   .newInstance();
                     Class articleServiceClass = Class.forName(config
                                   .getInitParameter("articleServiceClassName"));
                     Constructor con1 = articleServiceClass
                                   .getConstructor(new Class[] { Article.class });
                     Object articleService = con1                             
                                   .newInstance(new Object[] { articleDao });
                     config.getServletContext().setAttribute(
                                   ArticleService.class.getName(), articleService);
               } catch (Exception e) {
                     throw new ServletException(e.getMessage(), e);
               }
          }
        public void service(ServletRequest arg0, ServletResponse arg1)
                     throws ServletException, IOException {
              // TODO Auto-generated method stub
     }
}
l        构建视图层 JSP 页面
注意:
1 Web.xml中的<welcome-file>中的文件不能是映射的虚拟文件,如*.do形式的文件,否则找不到。
2最好把jsp页面放在应用程序的WEB-INF目录下以防外人恶意的链接。
            3Jsp文件中如果需使用大量的taglib标签库,那么往往是用一个专门的jsp文件来引入这些taglib标签库,然后其他的jsp文件使用时就只需使用include指令引入便可。例如:
如果a.jsp中专门引入taglib标签库,那么b.jsp在使用这些标签库时只需加入指令<%@ include file=”/a.jsp”>便可。
     用户模块:( Info.jsp Logon.jsp Register.jsp
            Info.jsp 是用来显示用户登录的信息, Logon.jsp 是一个登录页面, Register.jsp 是用来让用户填写注册信息的页面。前两者比较简单代码略,我们也可以根据自己的想法去设计。
Register.jsp  代码如下:
<%@ include file="/WEB-INF/jsp/comm/Header.jsp" %>
<form action="/sample/user/User.do" method="post" οnsubmit="return checkForm(this)">
     <input type="hidden" name="a" value="exe">
     <input type="hidden" name="m" value="regist">
     logon name: <input type="text" name="logonName"><br>
     nick name: <input type="text" name="nickName"><br>
     password: <input type="password" name="password"><br>
     re password: <input type="password" name="password1"><br>
     <input type="submit"> <input type="reset">
</from>
发贴模块:( ArticleForm.jsp show.jsp
ArticleForm.jsp 是一个用来发表帖子的表单页面,代码略。 Show.jsp 用来显示帖子详细信息的页面。代码如下:
   <%@ include file="/WEB-INF/jsp/comm/Header.jsp" %>
subject:<br>
title:${art.title}<br>
content:${art.content}<br>
issue:<fmt:formatDate value="${art.issue}" pattern="yyyy-MM-dd HH:mm:ss"/>
<c:if test="${session_user.id == art.author.id}">
           <a href="/sample/article/Article.do?m=edit&artId=${art.id}">edit</a>
</c:if><br>
author:<a href="/sample/user/User.do?m=showUserInfo&id=${art.author.id}" target="_blank">${art.author.nickName}</a>&nbsp;&nbsp;<br>
<hr>
comment:<br>
<c:forEach var="art" items="${children}">
         title:${art.title}<br>
         content:${art.content}<br>
         issue:<fmt:formatDate value="${art.issue}" pattern="yyyy-MM-dd HH:mm:ss"/>
         <c:if test="${session_user.id == art.author.id}">
              <a href="/sample/article/Article.do?m=edit">edit</a>
         </c:if><br>
        author:<a href="/sample/user/User.do?m=showUserInfo&id=${art.author.id}" target="_blank">${art.author.nickName}</a>&nbsp;&nbsp;<br>   
</c:forEach>
<hr>
comment:<br>
<form action="/sample/article/Article.do" method="post" οnsubmit="return checkForm(this)">
         <input type="hidden" name="a" value="exe">
         <input type="hidden" name="parentId" value="${art.id}">
         <input type="hidden" name="m" value="add">
         title: <input type="text" name="title"><br>
         content: <input type="text" name="content"><br>
         <input type="submit"> <input type="reset">
</from>
l 构造控制层
1 UserAction
该类是一个动态的 Action (继承 DispatchAction ),通过调用业务逻辑层接口实现用户的注册、登录、查询等功能。    
代码如下:
package com.sample.web.actions;
public class UserAction extends DispatchAction {
public ActionForward regist(ActionMapping mapping, ActionForm form,
               HttpServletRequest request, HttpServletResponse response)
               throws Exception {
          String a = request.getParameter("a");
          if ("exe".equals(a)) {// 判断是否已经填好信息
               String logonName = request.getParameter("logonName");
               String nickName = request.getParameter("nickName");
               String password = request.getParameter("password");
               User user = new User();
               user.setLogonName(logonName);
               user.setNickName(nickName);
               user.setPassword(password);
              // 注册
               this.getUserService().regist(user);
              // 使用 response.sendRedirect ()而不是用 findForward 来防止重复提交信息
               response.sendRedirect("/sample/user/User.do?m=showUserInfo&id="
                             + user.getId());
               return null;
           } else
               return mapping.findForward("regist");
     }
 // 显示用户信息
       public ActionForward showUserInfo(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)
               throws Exception {
               String id = request.getParameter("id");
         User user = this.getUserService().getUserById(Integer.parseInt(id));
         request.setAttribute("user", user);
         return mapping.findForward("info");
     }
    public ActionForward logon(ActionMapping mapping, ActionForm form,
               HttpServletRequest request, HttpServletResponse response)
               throws Exception {
        String a = request.getParameter("a");
        if ("exe".equals(a)) {
               String logonName = request.getParameter("logonName");
               String password = request.getParameter("password");
               User user = this.getUserService().logon(logonName, password);
       // 把登录用户存到 session
               request.getSession().setAttribute("session_user", user);
               response.sendRedirect("/sample/Home.do");
               return null;
         }
        return mapping.findForward("logon");
   }
 public ActionForward logout(ActionMapping mapping, ActionForm form,
               HttpServletRequest request, HttpServletResponse response)
               throws Exception {
        request.getSession().invalidate();
        response.sendRedirect("/sample/Home.do");
        return null;
 }
private UserService getUserService() {
        return (UserService) this.servlet.getServletContext().getAttribute(
                      UserService.class.getName());
 }
}
3 ArticleAction
该类也是一个动态的 Action (继承 DispatchAction ),通过调用 ArticleService 的方法来实现发贴,编辑,删除和显示。
程序代码如下:
              package com.sample.web.actions;
public class ArticleAction extends DispatchAction {
              public ActionForward add(ActionMapping mapping, ActionForm form,
                     HttpServletRequest request, HttpServletResponse response)
                     throws Exception {
                 this.isLogon(request);
                 String a = request.getParameter("a");
                 if ("exe".equals(a)) { // 判断用户是否是提交表单
                     Article art = new Article();
                     art.setTitle(request.getParameter("title"));
                     art.setContent(request.getParameter("content"));
                     art.setIssue(new Date());
                     art.setParentId(Integer.parseInt(request.getParameter("parentId")));
                     art.setAuthor(this.getLogonUser(request));
                     this.getArticleService().addArticle(art);
                     int artId = art.getId();
                     if (art.getParentId() > 0)   // 判断是否重贴
                            artId = art.getParentId();
                     response.sendRedirect("/sample/article/Article.do?m=show&artId="
                                   + artId);
                     return null;
               }
               request.setAttribute("operater", "add");
              return mapping.findForward("articleForm");
           }
           public ActionForward edit(ActionMapping mapping, ActionForm form,
                     HttpServletRequest request, HttpServletResponse response)
                     throws Exception {
              this.isLogon(request);
              String a = request.getParameter("a");
              System.out.println("a:" + a);
              if ("exe".equals(a)) {
              // 获得要编辑的文章
                     Article art = (Article) request.getSession().getAttribute(
                                   Article.class.getName());
                     request.getSession().removeAttribute(Article.class.getName());
                     art.setTitle(request.getParameter("title"));
                     art.setContent(request.getParameter("content"));
                // 更新文章
                     this.getArticleService().updateArticle(art,
                                   this.getLogonUser(request));
                     int id = art.getId();
                     if (art.getParentId() > 0)
                            id = art.getParentId();
                     System.out.println("id:" + id);
                     response.sendRedirect("/sample/article/Article.do?m=show&artId="
                                   + id);
                     return null;
              }
              int artId = Integer.parseInt(request.getParameter("artId"));
              Article art = this.getArticleService().getArticleById(artId);
              request.getSession().setAttribute(Article.class.getName(), art);
              request.setAttribute("operater", "edit");
              request.setAttribute("art", art);
              return mapping.findForward("articleForm");
           }
           public ActionForward del(ActionMapping mapping, ActionForm form,
                     HttpServletRequest request, HttpServletResponse response)
                     throws Exception {
              this.isLogon(request);
              int artId = Integer.parseInt(request.getParameter("artId"));
              this.getArticleService().delArticle(artId, this.getLogonUser(request));
              response.sendRedirect("/sample/Home.do");
              return null;
           }
           public ActionForward show(ActionMapping mapping, ActionForm form,
                     HttpServletRequest request, HttpServletResponse response)
                     throws Exception {
              int artId = Integer.parseInt(request.getParameter("artId"));
              Article art = this.getArticleService().getArticleById(artId);
              List<Article> children = this.getArticleService().getChildrenArticles(
                            artId);
              request.setAttribute("art", art);
              request.setAttribute("children", children);
              return mapping.findForward("show");
           }
           private void isLogon(HttpServletRequest request) {
              User user = this.getLogonUser(request);
              if (user == null)
                     throw new RuntimeException("no logon");
           }
          private User getLogonUser(HttpServletRequest request) {
              return (User) request.getSession().getAttribute("session_user");
           }
          private ArticleService getArticleService() {
              return (ArticleService) this.servlet.getServletContext().getAttribute(
                            ArticleService.class.getName());
          }
}
 
 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值