项目技术:Jsp+javascript+html

准备工作

   创建数据库:BBS_database.

   表的创建

       1.编辑字段:1.id(帖子及回复编号,设主键) 2.pid (当前帖子的父id,即被回复的帖子的id,原创则设为0)3.rootid (即原创的帖子id) 4.title (帖子的标题) 5.cont (帖子的内容) 6.pdate (帖子提交的时间) 7.isleaf (是否是叶子节点,是为0,不是为1)

       2.构建假数据。

1.新建1个web project

1)新建一个JSP页面(ShowArticleTree.jsp),利用递归实现文件树的呈现,列出已有的帖子的id及标题。

   1.连接数据库

       导入需要的jar包

       代码实现部分:

          Class.forName("com.mysql.jdbc.Driver");
           String url = "jdbc:mysql://localhost/bbs?user=root&password=123456";
           Connection conn = DriverManager.getConnection(url);

       使用递归算法遍历原创的回复帖子。

           代码实现部分:

          <%!

               String str = "";            //用来存储数据。

               private void tree(Connection conn, int id, int level) {

                   try {
                        stmt = conn.createStatement();
                        rs = stmt.executeQuery(sql);

                        while (rs.next()) {

                              str  += “此部分为html标签及要显示的数据”;

                              if (rs.getInt("isleaf") != 0) {                        //判断该帖子是否为叶子节点
                                      tree(conn, rs.getInt("id"), level+1);
                                 }

                        }

               }

           过程中遇到的问题

               *浏览器运行该页面时,刷新页面时,str里装的内容会重复显示。

           解决方法

               在str里的内容显示之后,把str置空。

           知识原理:

               服务器启动后只会产生一个servlet实例


2)新建一个JSP文件(ShowArticleDetail.jsp),用于点击标题的链接时显示详细内容

   利用递归算法遍历回复的帖子,代码参考ShowArticleTree.jsp文件

   利用链接传值

   例:<a href="Reply.jsp?id=<%= rs.getInt("id")%>&rootid=<%= rs.getInt("rootid") %>">回复</a>

3)新建一个JSP文件(Reply.jsp),用于在网页输入评论并提交。

   在页面显示一个文本框及一个文本编辑区域。

   内容提交到ReplyOK.jsp。

4)新建一个JSP文件(ReplyOK.jsp),用于接收回复帖子以及存入数据库

   接收数据格式:String title = request.getParameter("title");   //该方法返回数据类型为Sring,若需int类型则需要强制转换。

   文本输入换行问题:cont = cont.replaceAll("\n", "<br>");

   提交内容含中文乱码问题:request.setCharacterEncoding("gbk");

   使用PreparedStatement批量执行语句

       例子:String sql = "insert into article value(null,?,?,?,?,now(),0)";
                 PreparedStatement pstmt = conn.prepareStatement(sql);

                 pstmt.setInt(1,id);
                 pstmt.setInt(2,rootId);
                 pstmt.setString(3,title);
                 pstmt.setString(4,cont);
                 pstmt.executeUpdate();

                 pstmt.close();

     更新父帖的isleaf字段。

     更新数据时应放在一个transaction(事务,事务是恢复和并发控制的基本单位)里,代码实现:

                conn.setAutoCommit(false);

                                   ·····

                 conn.commit();
                 conn.setAutoCommit(true);                //恢复现场

5)新建一个JSP文件(Delete.jsp),用于删除帖子。

       连接数据库。

       使用递归算法删除子帖,并判断要删除的帖子父帖有无子帖,若无,则更新父帖的isleaf字段。

       判断父帖有无子帖方法:

                  Statement stmt = conn.createStatement();
                   ResultSet rs =

                   stmt.executeQuery("select count(*) from article where pid = " + pid);
                   rs.next();
                   int count = rs.getInt(1);

                   rs.close();

                   if (count <= 0) {
                   Statement stmtUpdate = conn.createStatement();
                   stmtUpdate.executeUpdate("update article set isleaf = 0 where id = " + pid);
                   stmtUpdate.close();
                   }

6) 新建一个Jsp文件(Post.jsp),用于发新帖子

       连接数据库。

       本文件将数据提交自身处理方法:

                  <form name="post" action="Post.jsp" method="post">
                       <input type="hidden" name="action" value="post">        //设置隐藏提交,在文件开始验证是否是本身文件提交数据

                   </form>

       文件开始验证代码:

                   String action = request.getParameter("action");                //接受form提交的信息

                   if (action != null && action.equals("post")) {

                                           ·······

                   }

       怎样确定帖子rootid(由于rootid即帖子本身id,帖子id由数据库本身自增控制,在帖子插入前    无法得到本身id)方法如下:

           执行sql语句时:

                   String sql = "insert into article value(null,0,?,?,?,now(),0)";

                   PreparedStatement pstmt =

                   conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);

           先设置rootid为

                   pstmt.setInt(1,-1);

           得到新生成的id

                  ResultSet rsKey = pstmt.getGeneratedKeys();
                   rsKey.next();
                   int Key = rsKey.getInt(1);
                   rsKey.close();

           然后更改帖子的rootid就可以了。

7) 新建一个jsp文件(Login.jsp),用于后台管理员登录页面。

8) 新建一个jsp文件(ShowArticleFlat.jsp),用于普通用户访问界面(只提供登录,浏览,发帖,回复功能,实现分页技术)

           实现分页步骤:

               1.确定1页显示数据量pageSize;

               2.确定数据总量totalRecords:

                       ResultSet rsCount = stmtCount.executeQuery("select count(*) from article where pid = 0");
                               rsCount.next();
                               int totalRecords = rsCount.getInt(1);

                     3.确定页数:

                       int totalPages = totalRecords % pageSize == 0 ? totalRecords / pageSize : totalRecords / pageSize + 1;

                    4.确定数据起始位置:

                       int startPos = (pageNo - 1) * pageSize;

               5.sql语言分页:

                       select * from article where pid = 0 order by pdate desc limit   startPos ,pageSize

                 6.分别使用下拉列表,输入目标页数和连接实现翻页查看

                       下拉列表实现代码:

                             <form name="form1" action="ShowArticleFlat.jsp">
                                          <select name="pageNo" οnchange="document.form1.submit()">
                                           <%
                                                    for(int i=1; i<=totalPages; i++) {
                                            %>
                                        <option value=<%= i%> <%= (i == pageNo) ? "selected" : "" %>>第<%=i%>页</option>
                                           <%
                                                    }
                                             %>
                                          </select>
                                   </form>

                               目标定向翻页实现代码:

                         <form name="form2" action="ShowArticleFlat.jsp">
                                            <input type="text" size="4" name="pageNo" value=<%= pageNo %> />
                                            <input type="submit" value="go"/>
                                   </form>

                               超链接实现代码:

                            <a href="ShowArticleFlat.jsp?pageNo=1">首页</a>
                                       <a href="ShowArticleFlat.jsp?pageNo=<%= pageNo - 1%>">上一页</a>&nbsp;&nbsp;
                                       <a href="ShowArticleFlat.jsp?pageNo=<%= pageNo + 1%>">下一页</a>
                                       <a href="ShowArticleFlat.jsp?pageNo=<%= totalPages%>">末页</a>



解决关于通过地址访问修改数据方法:

           通过session存放数据用于验证是否正常访问。

                  例: session.setAttribute("admin","true");

           在需要控制的页面上添加如下代码:

                   String admin = (String) session.getAttribute("admin");
                       //out.println(admin);
                       if (admin != null && admin.equals("true")){
                        login = true;
                       } else {
                        out.println("当前网页不可访问,请登录之后再做操作");
                        return;

                       }

               注:return作用:停止页面进行下去。

关于校验提交内容是否为空实现代码

                   <script language="javascript">
                           <!--
                                //javascript去除空格函数
                                 function LTrim(str) {  //去除字符串的 头空格
                                      var i;
                                      for(i=0; i<str.length; i++){
                                           if(str.charAt(i) != " ") break;
                                              }
                                      str = str.substring(i,str.length);
                                      return str;
                                  }

                                 function RTrim(str) {
                                      var i;
                                      for(i=str.length-1; i>=0; i--){
                                           if(str.charAt(i) != " " && str.charAt(i) != " "){
                                               break;
                                           }
                                          }
                                      str = str.substring(0,i+1);
                                      return str;
                                      }

                                   function Trim(str){
                                          return LTrim(RTrim(str));
                                     }

                                 function check() {
                                      if(Trim(document.post.title.value) == "") {
                                           alert("请输入标题");
                                           document.post.title.focus();
                                           return false;
                                          }

                                      if(Trim(document.post.cont.value) == "") {
                                           alert("请输入内容");
                                           document.post.cont.focus();
                                           return false;
                                      }

                                      return true;
                                        }
                           -->
                        </script>

                        <form name="post" action="Post.jsp" method="post" οnsubmit="return check()">

                                               ········

                       </form>