bbs

来源:互联网 发布:学java看什么书好 编辑:程序博客网 时间:2024/06/10 03:44

conn.jsp
<%
  String sql="";
  Connection con = null;
  try{  // 思考:这儿只有上括号 ,那么下括号在哪儿呢
   if (pool.getDriver()==null){
     pool.setDriver("sun.jdbc.odbc.JdbcOdbcDriver");
     //pool.setURL("jdbc:odbc:bbs");         //ODBC 的写法,比较通用
     pool.setURL("jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=E:/tomcat-5.0.27_teach/webapps/ROOT/db1.mdb");   //改成 SQL SERVER 的写法
     pool.setSize(5);
     pool.initializePool();
   }
   con = pool.getConnection();
   java.sql.Statement statement = con.createStatement();
%>
disconn.jsp
  <%
  pool.releaseConnection(con);
  }    //  思考:与哪个相对应
    catch (Exception e)
    {
      out.println(e.getMessage());
    }
%>
CSS.css
<style type=text/css>
<!--
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
a {color:000000;text-decoration:none }
a:visited{color:#0000FF;text-decoration:none }
a:hover{color:#000000;text-decoration:underline }
a:active {color:green;text-decoration:underline }
body {font-family:宋体; font-size: 10pt;}
table {font-family:宋体; font-size: 9pt;}

.input {
   border: 1px solid #062F5B;
   padding-left: 4;
   padding-right: 4;
   padding-top: 1;
   padding-bottom: 1;
  
}
.tabletop {
    font-weight :bolder;
    height: 24px;
    text-align: center;
 font-size: 12px;
 color: #ffffff;
 background-color:#218EC6;
}
-->
</STYLE>

login.jsp
 <html>
<head>
<title>BBS登录</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
???导入 css文件,语法如  <link rel="stylesheet" type="text/css" href="CSS文件">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p align=center>登录BBS</p>
??? 填入表单的开始标签,并填入属性:表单名为 "FM" ,表单数据提交的目标地址为checklogin.jsp页面
<table width="50%" border="1" align="center"><tr>
      <td width="37%">用户名: </td>
      <td width="63%"><input type="text" name="name"><!--在实际项目中每个输入框都要有长度限制,自己试试,用 maxlength 实现-->  </td>
</tr><tr>
      <td width="37%">密码:</td>
      <td width="63%">???这儿是密码输入框,输入框的名字是 "password"
      </td></tr>
<tr><td colspan=2 align="center">
       <a href="javascript:FM.submit();">提交</a>&nbsp;&nbsp;
       <a href="javascript:FM.reset();">取消</a>
     ???自己把这两个文字提交的方式换成用按钮提交的方式
</td></tr>
</table>
</form>
</body>
</html>

checklogin.jsp

--------------------------------------------------------------------------------
    
<%@ page import="java.sql.*"  contentType="text/html;charset=GB2312" %>
<HTML>
<BODY>
<jsp:useBean id="pool" scope="application" class="chapter10.ConnPool"/>   ???试试 把此语句用另外一种写法表示
<%
boolean success=true;
boolean disable=false;
String name=new String(request.getParameter("name").getBytes("ISO8859_1"),"GBK");  //将中文字符转换成标准字符的写法
String password=new String(request.getParameter("password").getBytes("ISO8859_1"),"GBK");%>
<%@ include file="conn.jsp"%> 
<%
    ??? 构造 SQL 语句赋给变量 sql , SQL语句为:读Users表中所有字段,条件是Name字段和Password字段的值与上述得到的值相等
  ResultSet rs =statement.executeQuery(sql);
  if (rs.next())
   {
       disable=rs.getBoolean("Disable");
     if (disable)
   {success=false;}
      } else{
     success=false;
     }
%>
  ??? 此处导入释放数据库连接的文件"disconn.jsp" ,参考导入申请释放数据库连接的文件
<%
if (success){
 session.setAttribute("Name",name);  // 思考:为什么用session 存放此变量,还有什么变量能存在session中
 response.sendRedirect("list.jsp");      // 页面跳转 ,试试用另一种方式表现
}else if (disable){%>
该用户已经被禁用!
<%}else{%>
用户名或密码有误,请重新登录!
<%}%>
<a href="javascript:history.back();">返回</a>
</BODY>
</HTML>
 
list.jsp

--------------------------------------------------------------------------------
    
//这个页面根据传入参数不同,分别实现了主贴列表和回帖列表的功能
<%@ page import="java.util.*, java.sql.*" contentType="text/html;charset=GB2312" %>
<HTML>
???导入 css文件
<BODY>
<%
 // 查看session 的值判断是否登录,防止非法用户直接输入此页面地址进入系统
if (session.getAttribute("Name")==null)
  {
        ??? 页面直接转向 login.html ,语法response.sendRedirect("")
  }
%>
<%
int PageSize=5; //一页显示的记录数
int RowCount; //记录总数
int PageCount; //总页数
int Page; //待显示页码
int i,j;
String strPage = request.getParameter("page");   // ???思考page参数从哪儿传来的,一般此页面从哪儿点出来,参数就从哪儿传出来的,如果没有传入,则此值为null
String id = request.getParameter("id");                  // ???思考id参数从哪儿传来的
String type=request.getParameter("type");           // ???此页面根据type的值不同将做不同的事情,当为article时显示主贴,当为re时显示某贴的回复贴
??? 当type 为null时,type赋初值article
if (strPage==null){
//表明在QueryString中没有page这一个参数,此时显示第一页数据
 Page = 1;
} else{
        //将字符串转换成整型 ,获得页码
 Page = Integer.parseInt(strPage);
 if(Page<1) Page = 1;
}%>
<jsp:useBean id="pool" scope="application" class="chapter10.ConnPool"/>
<%@ include file="conn.jsp"%>
<%
//判断是否为管理员
  sql= ??? 构造查询语句的字符串赋给变量 sql ,从Users表中取IsAdmin字段,条件是字段name等于登陆的名字,想想如何取得登陆的名字 :session.getAttribute("")
  ResultSet rs=statement.executeQuery(sql);
  rs.next();  //???思考:为什么rs要下移
  boolean IsAdmin=rs.getBoolean(1);   //???写出另一种从rs中取值的方法
  ??? 关闭rs ,用close()方法
  //根据type判断是文章列表还是回复文章列表,然后得到文章总数
  if (type.equals("re")){
   sql="select count(*) from ReArticles where ArticleId="+id;
  }else{
   sql= ???查出Articles表的所有记录数
  }
  rs =statement.executeQuery(sql);
  rs.next();
  RowCount =rs.getInt(1);  // ??? 思考:getInt(1) 得到是什么字段的值
  rs.close();
 
  PageCount = (RowCount+PageSize-1) / PageSize;  //记算总页数
  if(Page>PageCount) Page = PageCount;  //调整待显示的页码
  if (type.equals("re")){   //设置获取数据SQL语句
// ???写出这个sql语句的意思,与下句sql语句有何不同
   sql = "select Users.Name,PostDate,ReArticles.ID,Title"
    +" from ReArticles, Users where ReArticles.AuthorId=Users.ID and ReArticles.ArticleId="+id;
  }else{
   sql = "select Users.Name,PostDate,Articles.ID,Title"
    +" from Articles, Users where Articles.AuthorId=Users.ID";
  }
  rs = statement.executeQuery(sql);  // 执行SQL语句并取得结果集
  i = (Page-1) * PageSize;  // 将记录指针定位到待显示页的第一条记录之前
  //???思考:如果当前页为第一页,以下循环将如何运行,这样会不会出什么问题
  for(j=0;j<i;j++)
    rs.next();
%>
<p align=center>小型BBS</p>
<table border="1" cellspacing="0" cellpadding="0" width=80% align=center>
<tr><td colspan=2 align=center>
<%
  if (IsAdmin)  // 是管理员才有用户管理
   {
%>
<a href="usermanage.jsp">用户管理</a>&nbsp;&nbsp;
<%
}
%>
<%
if (type.equals("article"))    //表示是文章列表
{
%>
 <a href="modify.jsp ">发表文章</a>
    ??? 上面传入modify.jsp 时还要传入两个参数,type= article用于表示发表新贴而不是回复帖子(回帖用type=re),work=write 用于表示是发表新的文章(编辑文章用 work=modify 表示)
 &nbsp&nbsp<a href="login.html">退出</a>
<%
}
 else  //表示是回帖文章列表
{
%>
 <a href="modify.jsp?type=<%=type%>&id=<%=id%>&work=write">发表文章</a>
        ???思考:在连接到modify.jsp时传出的参数 type、id、work 分别起什么作用
 &nbsp&nbsp<a href="detail.jsp?type=article&id=<%=id%>">返回</a>
        ???思考:在连接到detail.jsp时传出的参数 type、id 分别起什么作用
<%
}
%>
</td>
</tr>
<%
i = 0;
while(i<PageSize && rs.next())  //???思考:这个循环的起止分别在哪儿
{
String reid=rs.getString(3);          //???思考getString(3)这种写法会不会不妥,有没有更好的方法
String title=rs.getString(4);
String postdate=rs.getString(2);
String author=rs.getString(1);%>
<tr>
<td>发表日期:<%=postdate%></td>
<td>作者:<%=author%></td>
</tr>
<tr>
<%if (IsAdmin){%>  //  如果是管理员所有文章都能删除
 <%if (type.equals("article")){%>
  <td>标题:<a href="detail.jsp?type=<%=type%>&id=<%=reid%>"><%=title%></a></td>
  <td><a href="delete.jsp?type=<%=type%>&id=<%=reid%>">删除</a></td>
 <%}else{%>
  <td>标题:<a href="detail.jsp?type=<%=type%>&id=<%=reid%>&articleid=<%=id%>"><%=title%></a></td>
  <td><a href="delete.jsp?type=<%=type%>&id=<%=reid%>&articleid=<%=id%>">删除</a></td>
 <%}
}else{%>    //非管理员则只有自己的文章能删除
 <%if (type.equals("article")){%>
  <td>标题:<a href="detail.jsp?type=<%=type%>&id=<%=reid%>"><%=title%></a></td>
  <%if (author.equals(session.getAttribute("Name"))){%> // 判断是否本人 
   <td><a href="delete.jsp?type=<%=type%>&id=<%=reid%>">删除</a></td>
  <%}
 }else{%>
  <td>标题:<a href="detail.jsp?type=<%=type%>&id=<%=reid%>&articleid=<%=id%>"><%=title%></a></td>
  <%if (author.equals(session.getAttribute("Name"))){%>    // 判断是否本人
   <td><a href="delete.jsp?type=<%=type%>&id=<%=reid%>&articleid=<%=id%>">删除</a></td>
  <%}
 }
}
//??? 分析每个删除的不同点,以及每个参数的含义
%>
</tr>
<%
i++;  //注意i起的作用
}
%>
<tr>
<td colspan=2 align=center>
第<%=Page%>页&nbsp&nbsp共<%=PageCount%>页 
<%
// ???这个判断起什么作用
if(Page<PageCount)
{
%>
<a href="list.jsp?page=<%=Page+1%>&id=<%=id%>&type=<%=type%>">下一页</a>
???每个参数起什么作用,参数能不能少一个(本页面接受的所有参数都要向下传播,否则查询的方式可能会改变)
<%
}
if(Page>1)
{
%>
<a href="list.jsp?page=<%=Page-1%>&id=<%=id%>&type=<%=type%>">上一页</a>
???每个参数起什么作用
<%
}%>
</td>
</tr>
</table>
<%@ include file="disconn.jsp"%>
</BODY>
</HTML>
 
detail.jsp

--------------------------------------------------------------------------------
    
//也是根据type的不同实现不同功能,为article时显示主贴详细内容,为re时显示回帖的详细内容

<%@ page import="java.util.*, java.sql.*" contentType="text/html;charset=GB2312" %>
<HTML>
???导入 css文件
<BODY>
<jsp:useBean id="pool" scope="application" class="chapter10.ConnPool"/>
??? 当发现没有登录时页面转向login.html
???导入申请数据库连接的页面
<%
String type=request.getParameter("type");     //type 为article 时显示主贴的详细内容,为re时显示回复贴的详细内容
  if (type==null) type="article";            // 注意对null的处理方法,null出错是最常见的错误之一
  String id=request.getParameter("id");
  String articleid=request.getParameter("articleid");

  ??? 判断语句:当type值为article 时执行下列语句
{
    // ???写出这个sql语句的意思,与下句sql语句有何不同
   sql="select Users.Name as Author,PostDate,Title,Content from Articles,Users "
    +"where Articles.ID="+id+" and Users.ID=Articles.AuthorId";
  }else{
   sql="select Users.Name as Author,PostDate,Title,Content from ReArticles,Users "
    +"where ReArticles.ID="+id+" and Users.ID=ReArticles.AuthorId";
  }

??? 执行查询语句sql ,得到数据集rs
  rs.next();
  String postdate=  ???从rs中取 PostDate 字段的值
  String author=    ???从rs中取 Author字段的值
  String title=      ???从rs中取 Title字段的值
%>
<table border="1" cellspacing="0" cellpadding="0" width=60% align=center>
<tr><td colspan=2 align=center>

??? 判断 author 是否为作者
<a href="modify.jsp?type=<%=type%>&id=<%=id%>&articleid=<%=articleid%>&work=modify">修改</a>&nbsp&nbsp
//???说出每个参数的含义
<a href="delete.jsp?type=<%=type%>&id=<%=id%>&articleid=<%=articleid%>">删除</a>&nbsp&nbsp
<%
}
??? 判断当前页是否主贴,是则有以下回复文章的链接
{
%>
 <a href="modify.jsp">回复文章</a>&nbsp&nbsp
    ??? 上面modify.jsp 页面后还要有三个参数 type 表示是回帖,id 表示对哪个主贴进行回帖,work=write 表示发表新的文章
 <a href="list.jsp?type=re&id=<%=id%>">查看回复文章</a>&nbsp&nbsp
    ???  上面list.jsp 页面后还要有两个参数 type 表示查看的是回帖,id 表示查看哪个主贴的回帖回帖
<%
}
%>
<a href="list.jsp?type=<%=type%>&id=<%=articleid%>">返回</a></td></tr>
<tr><td>发表日期:</td><td><%=postdate%><td><tr>
<tr><td>作者:</td><td><%=author%><td><tr>
<tr><td>标题:</td><td><%=title%><td><tr>
<%
String temp=rs.getString("Content");
  String content="";
  for (int i=0;i<temp.length();i++){
    //注意:在文本中换行用 /n 表示,在网页中换行用什么表示呢
   if (temp.charAt(i)==/n){
    content+="<br>";
   }else{
    content+=temp.charAt(i);
   }
  }
%>
<tr><td colspan=2>  ??? 显示content 的内容  </td></tr>
</table>
???导入数据库释放的页面
</BODY>
</HTML>

 
   
//此页面根据参数work取值不同实现不同功能,work=write 表示发表新文章,work=modify 表示修改文章,type=article 表示对主贴进行操作,type=re表示对回帖进行操作
??? 设置 jsp 页面属性 即设置 page
<HTML>
???导入 css文件
<BODY>
<%
  chapter10.ConnPool pool = new chapter10.ConnPool();  //  导入javabean 的普通写法,很多公司更偏向用此写法
%>
??? 当发现没有登录时页面转向login.html
<%
String type=request.getParameter("type");
??? 当没有type参数传入时,type赋初值 article
  String id=request.getParameter("id");
  String articleid=request.getParameter("articleid");
  String work=request.getParameter("work");
  ??? 当没有work参数传入时,work 赋初值 write
  %>
???导入申请数据库连接页面
<table border="1" cellspacing="0" cellpadding="0" width=60% align=center>
<form name="FM" method="post"  >
???上面表单提交后的处理页面是本页checkmodify .jsp
??? 用隐藏域 将接受的type 的值向提交的页面传递
??? 用隐藏域 将接受的work的值向提交的页面传递
<%
 ??? 如果type 表示回帖
{
%>
???用隐藏域 将接受的id 的值向提交的页面传递
<%
}
%>
<tr><td colspan=2 align=center><a href="javascript:FM.submit();">确定</a>
&nbsp&nbsp<a href="javascript:history.back();">取消</a></td></tr>
<%
if (work.equals("write"))   // 判断是发新贴
{
   if (type.equals("article"))  // 判断是对主贴操作
{
%>
 <tr><td>标题:</td><td><input type="text" name="title"></td></tr>
<%
}
else  //判断对回帖操作
{
      sql="select Title from Articles where ID="+id;
      ResultSet rs=statement.executeQuery(sql);
      rs.next();
      String title=rs.getString("Title");
%>
 <tr><td colspan=2>标题:Re <%=title%></td><tr>
 <input type="hidden" name="title" value="Re <%=title%>">
 <input type="hidden" name="id" value="<%=id%>">
<%
rs.close();
 }
%>
<tr><td colspan=2><textarea name="content" rows="50" cols="100"></textarea></td></tr>
<%
}
else   // 否则是修改帖子
{
  if (type.equals("article"))  // 判断是修改主贴
{
     sql="select PostDate,Title,Content from Articles "
      +"where Articles.ID="+id;
      }
else                  // 判断是修改回帖
{
     sql="select PostDate,Title,Content from ReArticles "
    +"where ReArticles.ID="+id;
  }
  ResultSet rs =statement.executeQuery(sql);
  rs.next();
  String title=rs.getString("Title");
  %>
<tr><td>发表日期:</td><td><%=rs.getString("PostDate")%></td></tr>
<tr><td>标题:</td><td><%=title%></td>
<input type="hidden" name="title" value="<%=title%>">
<input type="hidden" name="id" value="<%=id%>">
<input type="hidden" name="articleid" value="<%=articleid%>">
</tr>
<tr><td colspan=2><textarea name="content" rows="50" cols="100"><%=rs.getString("Content")%></textarea></td></tr>
<%}%>
</form>
</table>
???释放数据库连接的页面
</BODY>
</HTML>
   ??? 设置 jsp 页面属性 即设置 page
<HTML>
??? 导入CSS
<BODY>
??? 申明javabean , j将chapter10.ConnPool 初始化后赋给变量pool
<%if (session.getAttribute("Name")==null){
 response.sendRedirect("login.html");
}%>
<%
  String type=request.getParameter("type");
  String id=request.getParameter("id");
  String articleid=request.getParameter("articleid");
  String work=request.getParameter("work");
  String title=request.getParameter("title");
  String content=request.getParameter("content");
 
  Calendar cal=Calendar.getInstance();
  String postdate=cal.get(Calendar.YEAR)+"-"+cal.get(Calendar.MONTH)+"-"+cal.get(Calendar.DATE);
  // 以上是用JSP 获取系统时间的写法,但真正系统中系统时间必须获取数据库服务器的时间
  %>
  <%
if (title.equals("") || content.equals(""))  //???思考 什么情况下title 或content 会出现null
{
%>
  标题和文章内容均不能为空!<br>
  <a href="javascript:history.back();">返回</a>
 // ???注意在href 中除了连接页面外,可以用javascript进行跳转
  <%
}
else
{
%>
 <%@ include file="conn.jsp"%> 
 <%
sql= // ??? 从Users表中查询ID字段,条件是字段Name的值等于登录的名字
   ResultSet rs=statement.executeQuery(sql);
   rs.next();
   int authorid=rs.getInt("ID");
   out.print(type+work);
   title=new String(title.getBytes("iso8859-1"), "gb2312");
   content=new String(content.getBytes("iso8859-1"), "gb2312"); 
   //注意以上是转换成中文的写法,否则会出现乱码
   if (type.equals("article")){     // 主贴则对 Articles进行操作
    if (work.equals("write")){  // 发新贴
     sql="insert into Articles (AuthorId,PostDate,Title,Content) values ("
     +authorid+","+postdate+","+title+","+content+")";
    }else if (work.equals("modify")){  //修改帖子
     sql="update Articles set PostDate="+postdate+",Content="+content+" where ID="+id;
    }
   }else if (type.equals("re")){ // 回帖则对 ReArticles进行操作
    if (work.equals("write")){      // 发新贴
     sql="insert into ReArticles (ArticleId,AuthorId,PostDate,Title,Content) values ("
     +id+","+authorid+","+postdate+","+title+","+content+")";   
    }else if (work.equals("modify")){    //修改帖子
     sql="update ReArticles set PostDate="+postdate+",Content="+content+" where ID="+id;
    }
   }
    // ???执行数据更新语句,注意与执行查询语句的区别。语法statement.executeUpdate("") ,增加、修改、删除均用这个写法
 %>
 <%@ include file="disconn.jsp"%>
 <%
if (work.equals("write"))
{
   ??? 转向list.jsp页面,同时传给id的值及type 的值,返回时传值一般是保持原先页面的状态,想想这两个值是保持原先什么状态,去掉后将如何 ,(id对主贴没有用,只对回帖有用)
   }
else if (work.equals("modify"))
{
    if (type.equals("article"))
{
     ??? 在转向detail.jsp页面,同时传给id的值及type 的值
    }
else if (type.equals("re"))
{
     ??? 转向detail.jsp页面,同时传给id的值、type 的值和articleid的值
    }
   }
 }
%>
</BODY>
</HTML>

??? 设置 jsp 页面属性 即设置 page
<HTML>
<BODY>
??? 申明javabean , j将chapter10.ConnPool 初始化后赋给变量pool
<%
???若没登录,转向login.html
???得到传来的type
???当type为空时,赋初值article
???得到传来的id
???得到传来的articleid

  %>
<%@ include file="conn.jsp"%>
<% 
if (type.equals("article")){   // 如果删除主贴,则要把其回帖全部删除
   sql=  ??? 从ReArticles表中删除记录,条件是字段ArticleId的值为上面得到的id
   ??? 执sql 语句
   sql=  ??? 从Articles表中删除记录,条件是字段ID的值为上面得到的id
   ??? 执sql 语句
  }else{ // 否则只删除回帖
   sql= ??? 从ReArticles表中删除记录,条件是字段ID的值为上面得到的id
   ??? 执sql 语句
  }
%>
<%@ include file="disconn.jsp"%>
<%
???如果删除的是主贴,则返回list.jsp
if (type.equals("article")){
 response.sendRedirect("list.jsp?type=article&id="+id);
  }else{
response.sendRedirect("list.jsp?type=re&id="+articleid);
??? 转向list.jsp页面,思考为什么 这儿id的值跟上面的写法不同
  }
%>
</BODY>
</HTML>

usermanage.jsp

--------------------------------------------------------------------------------
    
??? 设置 jsp 页面属性 即设置 page
<HTML>
<BODY>
<%if (session.getAttribute("Name")==null){
 response.sendRedirect("login.html");
}%>
<%
int PageSize=5; //一页显示的记录数
int RowCount; //记录总数
int PageCount; //总页数
int Page; //待显示页码
int i,j;
String strPage = request.getParameter("page");
String type = request.getParameter("type");
String userid = request.getParameter("id");
if (strPage==null)
{
//表明在QueryString中没有page这一个参数,此时显示第一页数据
 Page = 1;
}
else
{
//将字符串转换成整型
 Page = Integer.parseInt(strPage);
 if(Page<1) Page = 1;
}
%>
<jsp:useBean id="pool" scope="application" class="chapter10.ConnPool"/>
<%@ include file="conn.jsp"%>
<%  //判断是否为管理员
   sql=   ???从 Users表中选取IsAdmin字段,条件是字段Name 的值为登录的名字
??? 执行查询语句
??? 查询所得的数据集的指针向下移动一位
??? 申明字段IsAdmin 为布尔型,然后从查询结果中取IsAdmin字段的值赋给变量IsAdmin
   ???结果集关闭
%>
<%
??? 如果是管理员
{      
 if (type!=null){
  if (type.equals("delete")){                                // 删除
   sql= ??? 从Users表中删除记录,条件是字段ID的值为传入的用户ID  
  }else if (type.equals("chadmin")){                         //更改管理员权限
   sql="update Users set IsAdmin = not IsAdmin where ID="+userid; // 更改用户管理员权限
  }else if (type.equals("chdisable")){                        // 更改禁用
   sql= ???更新Users表,使Disable字段的值与以前相反(Disable为布尔型),条件是字段ID的值为传入的用户ID ,参考上面语句
  }
        ??? 执行数据更新语句
 }
 
 //得到记录总数
 sql= ???得到Users的总记录数
 rs = ???执行查询语句并把结果集返回给 rs 变量
 ???记录集指针下移
 RowCount = ??? 从rs 中得到第一个值,并把值赋给RowCount
 ???记录集关闭
 
 PageCount = (RowCount+PageSize-1) / PageSize;  //记算总页数
 if(Page>PageCount) Page = PageCount;  //调整待显示的页码
 sql = "select * from Users";
 rs = statement.executeQuery(sql);  //执行SQL语句并取得结果集
 i = (Page-1) * PageSize;  //将记录指针定位到待显示页的第一条记录之前
 for(j=0;j<i;j++) rs.next();
%>
<center><h2>用户管理</h2></center>
<center>共有用户<%=RowCount%>名&nbsp&nbsp&nbsp&nbsp
<a href="list.jsp">返回主菜单</a>&nbsp&nbsp<a href="login.html">退出</a></center>
<table border="1" cellspacing="0" cellpadding="0" width=60% align=center>
<tr><td>编号</td><td>姓名</td><td>是否管理员</td><td>是否被禁用</td><td>删除</td></tr>
<%
i = 0;
while(i<PageSize && rs.next())
{
 String id=rs.getString("ID");
 String name=rs.getString("Name");
 String email=rs.getString("Email");
 boolean isadmin=rs.getBoolean("IsAdmin");
 boolean disable=rs.getBoolean("Disable");%>
<tr>
<td><%=i%></td>
<td><%=name%></td>
<td>
<%
???如果是管理员则在页面上显示"是",否则显示"否"
%>
&nbsp&nbsp<a href="usermanage.jsp">更改</a>
  ??? 上面连接到usermanage.jsp时还要传入type=chadmin表示修改是否管理员属性,同时还要传入用户的id值
</td>
<td>
<%
 ???如果此帐号已经禁用则在页面上显示"是",否则显示"否"
%>
&nbsp&nbsp<a href="usermanage.jsp">更改</a> 
??? 上面连接到usermanage.jsp时还要传入type= chdisable表示更改是否禁用,同时还要传入用户的id值

</td>
<td><a href=usermanage.jsp>删除</a></td>
??? 上面连接到usermanage.jsp时还要传入type=delete表示删除此用户,同时还要传入此用户的id值

</tr>
<%
 i++;
}
 %>
<tr>
<td colspan=5 align=center>
第<%=Page%>页&nbsp&nbsp共<%=PageCount%>页 
???上下分页的连接,连接到本页
</td>
</tr>
</table>
<%
}   ???思考与哪个上括号对应
else
{
 response.sendRedirect("login.html");
}%>
<%@ include file="disconn.jsp"%>
</BODY>
</HTML>

???以上页面当修改管

 
register.html

--------------------------------------------------------------------------------
     ??? 用户注册页面,要提供的信息有用户名(对应字段为name)、密码(对应字段为password1)、密码确认(对应字段为password2)、电子邮箱(对应字段为email)。在提交时对相应字段在客户端进行验证
 
 
checkregister.jsp

--------------------------------------------------------------------------------
    
//将注册信息保存在数据库
<%@ page import="java.util.*, java.sql.*" contentType="text/html;charset=GB2312" %>
<HTML>
<BODY>
<jsp:useBean id="pool" scope="application" class="chapter10.ConnPool"/>
<%String name=new String(request.getParameter("name").getBytes("ISO8859_1"),"GBK");
  String password1=new String(request.getParameter("password1").getBytes("ISO8859_1"),"GBK");
  String password2=new String(request.getParameter("password2").getBytes("ISO8859_1"),"GBK");
  String email=request.getParameter("email");
  boolean valid=true;                  //用于判断用户信息是否非法
  String err="";
%>
<%@ include file="conn.jsp"%>
<%
sql= ??? 查询Users表,看是否有名字跟输入的名字相同的
ResultSet rs=statement.executeQuery(sql);
if ???如果有记录
{
 err+="该用户名已经存在,请更换用户名!<br>";
 valid=false;
}
else if  ??? 用户名、密码其中任意一个为空
{
 err+="用户名、电子邮箱、密码和密码确认都不能为空!<br>";
 valid=false;
}else if ???两次密码不同
{
 err+="两次输入的密码不同!<br>";
 valid=false;
}
else
{
   ???将注册信息插入Users表中
}%>
<%@ include file="disconn.jsp"%>
<%if ??? 注册信息不正确
{
 response.sendRedirect("login.html");
}else{%>
 <%=err%>
 <a href="javascript:history.back();">返回</a>
<%}%>
</BODY>
</HTML>
 
据库结构

用户表 USERS:
ID            自动加1
Name          文本
Password      文本
Email         文
IsAdmin       是/否
Disable       是/否
 
文章对应的表 ARTICLES:
ID            自动加1
AuthorId      数字
PostDate      日期/时间
Title          文本
Content        文本
 
回复文章的表名REARTICLES:
ID           自动加1
ArticleId    数字
AuthorId     数字
PostDate     日期/时间
Title        文本
Content      文本
 
分页处理机制:
 
总页数=(记录总算+每页显示条数-1)/ 每页显示条数
 PageCount = (RowCount+PageSize-1) / PageSize; 
 当输入页数小于1时,或没有页码参数传入时,显示第一页,当大于总页数时,显示最后一页
 显示当前页面时:
 将查询出的记录集定位在本页的第一条记录上,然后循环到本页的最后一条记录,即可显示本页所有记录
 显示下一页时:
 将当前的页码数加1,然后将此参数传入本页面,此时页面将被刷新,但传入页码参数增1了,因而显示下一个页面的记录
 显示上一页时:
 将当前的页码数减1,然后将此参数传入本页面,此时页面将被刷新,但传入页码参数减1了,因而显示上一个页面的记录
在第一个页面时不显示上一页,在最后一个页面时不显示下一页
 
分页处理代码:
int PageSize=5; //一页显示的记录数
int RowCount; //记录总数
int PageCount; //总页数
int Page; //待显示页码
String strPage = request.getParameter("page");   
if (strPage==null){
//表明在QueryString中没有page这一个参数,此时显示第一页数据
 Page = 1;
} else{
        //将字符串转换成整型 ,获得页码
 Page = Integer.parseInt(strPage);
 if(Page<1) Page = 1;
   构造查询语句,查出记录总数
  PageCount = (RowCount+PageSize-1) / PageSize;  //记算总页数
  if(Page>PageCount) Page = PageCount;  //调整待显示的页码
 
  rs = statement.executeQuery(sql);  // 执行SQL语句并取得结果集
  i = (Page-1) * PageSize;  // 将记录指针定位到待显示页的第一条记录之前
  //???思考:如果当前页为第一页,以下循环将如何运行,这样会不会出什么问题
  for(j=0;j<i;j++)
    rs.next();
i = 0;
while(i<PageSize && rs.next())  //???思考:这个循环的起止分别在哪儿
{
显示记录的值
i++; 
}
第<%=Page%>页&nbsp&nbsp共<%=PageCount%>页 
<%
// ???这个判断起什么作用
if(Page<PageCount)
{
%>
<a href="list.jsp?page=<%=Page+1%>">下一页</a>
???每个参数起什么作用,参数能不能少一个(本页面接受的所有参数都要向下传播,否则查询的方式可能会改变)
<%
}
if(Page>1)
{
%>
<a href="list.jsp?page=<%=Page-1%>">上一页</a>

权限管理:
 是管理员会有用户管理,所有文章都能删除
 非管理员没有用户管理,只有自己发表的文章能删除
几个重要参数
 type 为 re 表示回复文章列表 ,为 article 表示文章列表
work=write 用于表示是发表新的文章(编辑文章用 work=modify