- use bookstore;
- create table guestbook(
- gst_id INT AUTO_INCREMENT not null primary key,
- gst_user VARCHAR(10) not null,
- gst_title VARCHAR(100) not null,
- gst_content TEXT,
- gst_time TIMESTAMP not null,
- gst_ip VARCHAR(15) not null);
2 JDBC资源池连接数据库 配置方法已经写了
3 say.html 填写留言信息
- <center>
- <form action="process.jsp" method="post">
- <table bgcolor="#B3B3FF">
- <caption>欢迎访问留言板</caption>
- <tr>
- <td>用户名:</td>
- <td><input type="text" name="name"></td>
- </tr>
- <tr>
- <td>主题:</td>
- <td><input type="text" name="title" size="40"></td>
- </tr>
- <tr>
- <td>内容:</td>
- <td>
- <textarea name="content" rows="10" cols="40"></textarea>
- </td>
- </tr>
- <tr>
- <td><input type="submit" value="提交"></td>
- <td><input type="reset" value="重填"></td>
- </tr>
- </table>
- </form>
- </center>
4 util.jsp 包含一个静态的工具方法toHtml() 用于对Html中的保留字符和一些特殊字符进行转换。因为用户在输入过程中可能会输入一些特殊字符 如果我们对这些字符不做相应的转换 那么用户输入的数据将不能正常显示。一方面保证数据的正常显示 一方面也保证了Web应用程序的安全性
- <%!
- public static String toHtml(String str)
- {
- if(str==null)
- return null;
- StringBuffer sb = new StringBuffer();
- int len = str.length();
- for (int i = 0; i < len; i++)
- {
- char c = str.charAt(i);
- switch(c)
- {
- case ' ':
- sb.append(" ");
- break;
- case '\n':
- sb.append("
"); - break;
- case '\r':
- break;
- case '\'':
- sb.append("'");
- break;
- case '<':
- sb.append("<");
- break;
- case '>':
- sb.append(">");
- break;
- case '&':
- sb.append("&");
- break;
- case '"':
- sb.append(""");
- break;
- case '\\':
- sb.append("\");
- break;
- default:
- sb.append(c);
- }
- }
- return sb.toString();
- }
- %>
5 process.jsp
向数据库中插入用户的留言。
- <%@ page contentType="text/html;charset=gb2312" %>
- <%@ page import="java.sql.*,javax.sql.*,javax.naming.*" %>
- <%@ include file="util.jsp" %>
- <%
- request.setCharacterEncoding("gb2312");
-
- String name=request.getParameter("name");
- String title=request.getParameter("title");
- String content=request.getParameter("content");
-
- if(null==name || null==title || null==content)
- {
- response.sendRedirect("index.jsp");
- return;
- }
-
- name=toHtml(name.trim());
- title=toHtml(title.trim());
- if(name.equals("") || title.equals(""))
- {
- response.sendRedirect("say.html");
- return;
- }
- content=toHtml(content.trim());
- String fromIP=request.getRemoteAddr();
-
- Context ctx=new InitialContext();
- DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/bookstore");
- Connection conn=ds.getConnection();
-
- PreparedStatement pstmt=conn.prepareStatement(
- "insert into guestbook(gst_user,gst_title,gst_content,gst_ip) values(?,?,?,?)");
- pstmt.setString(1,name);
- pstmt.setString(2,title);
- pstmt.setString(3,content);
- pstmt.setString(4,fromIP);
-
- pstmt.executeUpdate();
- pstmt.close();
- conn.close();
- response.sendRedirect("index.jsp");
- %>
说明:
[1] 第一行 利用page指令contentType属性设置页面的MIME类型是text/html 字符编码是gb2312
[2] 第二行 利用page的import属性导入在页面中需要用到的java类
[3] 第三行 利用include指令包含util.jsp 这样 在页面中就可以食用toHtml()方法了。
[4] 第26行 调用请求对象 getRemoteAddr()方法 得到客户端的IP地址 如果用户是通过代理服务器上网的 得到的是代理服务器的IP地址
[5] 利用数据源对象建立数据库的连接 留言时间的烈性是TIMESTAMP 插入时没有对这个进行赋值 MySQL会自动将该列设置为当前的日期和时间 这样我们在插入记录的时候就不用考虑插入当前时间的问题了
6 index.jsp 留言板的首页 用来显示用户的留言
- <%@ page contentType="text/html;charset=gb2312" %>
- <%@ page import="java.sql.*,javax.sql.*,javax.naming.*" %>
- <html>
- <head>
- <title>网上书店留言板</title>
- </head>
- <body>
- <a href="say.html">我要留言</a><br>
- <%
- Context ctx=new InitialContext();
- DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/bookstore");
- Connection conn=ds.getConnection();
-
- //创建可滚动的结果集。
- Statement stmt=conn.createStatement(
- ResultSet.TYPE_SCROLL_INSENSITIVE,
- ResultSet.CONCUR_READ_ONLY);
- ResultSet rs=stmt.executeQuery("select * from guestbook order by gst_time desc");
-
- //移动游标到结果集的最后一行。
- rs.last();
-
- //得到当前行的行数,也就得到了数据库中留言的总数。
- int rowCount=rs.getRow();
- if(rowCount==0)
- {
- out.println("当前没有任何留言!");
- return;
- }
- else
- {
- %>
- 共有<strong><%=rowCount%></strong>条留言
- <%
- }
-
- String strCurPage=request.getParameter("page");
-
- //表示当前的页数。
- int curPage;
-
- if(strCurPage==null)
- curPage=1;
- else
- curPage=Integer.parseInt(strCurPage);
-
- //定义每页显示的留言数。
- int countPerPage=2;
-
- //计算显示所有留言需要的总页数。
- int pageCount=(rowCount+countPerPage-1)/countPerPage;
-
- //移动游标到结果集中指定的行。如果显示的是第一页,curPage=1,
- //游标移动到第1行。
- rs.absolute((curPage-1)*countPerPage+1);
-
- //如果是第1页,则显示不带链接的文字,如果不是第1页,
- //则给用户提供跳转到第一页和上一页的链接。
- if(curPage==1)
- {
- %>
- 第一页
- 上一页
- <%
- }
- else
- {
- %>
- <a href="index.jsp?page=<%=1%>">第一页</a>
-
- <a href="index.jsp?page=<%=curPage-1%>">上一页</a>
-
- <%
- }
- //如果当前页是最后一页,则显示不带链接的文字,如果不是最后一页,
- //则给用户提供跳转到最后一页和下一页的链接。
- if(curPage==pageCount)
- {
-
- %>
- 下一页
- 最后页
- <%
- }
- else
- {
- %>
- <a href="index.jsp?page=<%=curPage+1%>">下一页</a>
-
- <a href="index.jsp?page=<%=pageCount%>">最后页</a>
-
- <%
- }
-
- int i=0;
-
- //以循环的方式取出每页要显示的数据,因为在前面针对要显示的页数,
- //调用了rs.absolute((curPage-1)*countPerPage+1);
- //所以是从游标所在的位置取出当前页要显示的数据。
- while(i<countPerPage && !rs.isAfterLast())
- {
- out.println("
"); - out.println("用户名:"+rs.getString("gst_user"));
- out.println(" ");
-
- Timestamp ts=rs.getTimestamp("gst_time");
- long lms=ts.getTime();
- Date date=new Date(lms);
- Time time=new Time(lms);
-
- out.println("留言时间:"+date+" "+time);
-
- out.println(" ");
- out.println("用户IP:"+rs.getString("gst_ip")+"
"); - out.println("主题:"+rs.getString("gst_title")+"
"); - out.println("内容:"+rs.getString("gst_content"));
- i++;
- rs.next();
- }
- rs.close();
- stmt.close();
- conn.close();
- %>
- </body>
- </html>
说明:
[1] 主要思路是利用可滚动的结果集来实现留言板的分页显示功能。
[2] 时间的显示 在调用Timestamp类的getTime()方法从1970年开始的毫秒数 利用java.sql.Date 和 java.sql.Time对象共同输出留言的时间 为什么不直接使用Timestamp 应该直接用rs.toString来输出时间得到的时间值是 2011-12-10 19:23:23.0 后面的.0是java语言显示时间本身的问题。