留言板功能需求:
1.页面效果如下图所示,应包含留言和管理员回复功能;
2.访客发布和显示只要一个JSP页面,页面最上方是发布内容区域;
3.管理员回复功能由另一个页面实现。
4.页面下方列出已有留言,还需显示提交时间;
5.留言数据存在服务器的数据库中;
留言发布页面board,jsp的核心代码:
Leave your traces!
<%
//如果用户提交信息 则插入数据库 其中头像为随机
if(request.getParameter("user")!=null)
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://url??useUnicode=true&characterEncoding=utf-8",用户名,密码);
Statement stat = conn.createStatement();
//参数化
String sql = "INSERT INTO MessageBoard(MDisplay, MIp, MName, MEmail, MTime, MSaying, MImage) VALUES(1,?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
//随机头像
int i=new Random().nextInt(10);
String muser=new String(request.getParameter("user").getBytes("iso-8859-1"),"utf-8");
String msaying=new String(request.getParameter("saying").getBytes("iso-8859-1"),"utf-8");
//设置参数
ps.setString(1,request.getParameter("sip"));
ps.setString(2,muser);
ps.setString(3,request.getParameter("email"));
ps.setString(4,request.getParameter("stime"));
ps.setString(5,msaying);
ps.setString(6,"img/head"+i+".png");
ps.executeUpdate();
stat.close();
conn.close();
}
%>
<% //获取页数
int pagei=0;
int maxp=0;
if(request.getParameter("page")!=null)
if(request.getParameter("page")!=""){
String str1=request.getParameter("page");
Pattern pattern = Pattern.compile("[0-9]*");
if(pattern.matcher(str1).matches())
pagei=Integer.parseInt(str1);
}
Connection conn = DriverManager.getConnection("jdbc:mysql://url?useUnicode=true&characterEncoding=utf-8",用户名,密码);
Statement stat = conn.createStatement();
//查询总记录数
String sql1 = "SELECT count(MyId) totalCount FROM MessageBoard WHERE MDisplay=1";
ResultSet rset = stat.executeQuery(sql1);
int rowCount = 0;
//获取总记录数
while(rset.next()) {
rowCount=rset.getInt("totalCount");
}
maxp=(rowCount-1)/10;
//计算页数
if((pagei*10+1)>rowCount)
pagei=maxp;
%>
<%
pagei*=10;
%>
<%
// 分页查询 pagei由程序计算生成 不是用户输入 因此不需要参数化
String sql = "SELECT Myid, MName, MTime, MSaying, MImage FROM MessageBoard WHERE MDisplay=1 ORDER BY MTime DESC limit "+pagei+" ,10 ";
ResultSet rs = stat.executeQuery(sql);
//把查询结果先保存下来
List mesIdlist = new ArrayList();
List mesNamelist = new ArrayList();
List mesTimelist = new ArrayList();
List mesSayinglist = new ArrayList();
List mesImglist = new ArrayList();
//打印留言信息
while(rs.next()){
mesIdlist.add(rs.getString("Myid"));
mesNamelist.add(rs.getString("MName"));
mesTimelist.add(rs.getString("MTime"));
mesSayinglist.add(rs.getString("MSaying"));
mesImglist.add(rs.getString("MImage"));
}
for(int ite=0;ite",">");
mesName=mesName.replaceAll("\"",""");
mesName=mesName.replaceAll(" "," ");
String mesHead = mesSaying.substring(0, 1);
String mesLast = mesSaying.substring(1);
mesLast=mesLast.replaceAll("<","<");
mesLast=mesLast.replaceAll(">",">");
mesLast=mesLast.replaceAll("\"",""");
mesLast=mesLast.replaceAll(" "," ");
%>
<%=mesName%>
<%=mesTime%>
<%
// 查询对应留言回复 mesId由程序计算生成 因此不需要参数化
String resql = "SELECT Retext, Rtime FROM ReplyBoard WHERE MyId="+mesId+" ORDER BY Rtime";
ResultSet res = stat.executeQuery(resql);
//打印留言回复
while(res.next()){
String mesReply = res.getString("Retext");
String mesRtime = res.getString("Rtime");
mesReply=mesReply.replaceAll("<","<");
mesReply=mesReply.replaceAll(">",">");
mesReply=mesReply.replaceAll("\"",""");
mesReply=mesReply.replaceAll(" "," ");
%>
Administrator reply: <%=mesReply%>
<%=mesRtime%>
<%
}
%>
<%
}
%>
<%
stat.close();
conn.close();
%>
<%
//分页按钮
if(pagei!=0){
%>
<%
}else{
%>
<%
}
%>
<%=pagei/10+1%>
/
<%=maxp+1%>
<%
if(pagei/10
<%
}else{
%>
<%
}
%>
管理员回复页面adm,jsp的核心代码:
Leave your traces!
<%
//如果用户提交信息 则插入数据库 其中头像为随机
if(request.getParameter("user")!=null)
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://url?useUnicode=true&characterEncoding=utf-8",用户名,密码);
Statement stat = conn.createStatement();
//参数化
String sql = "INSERT INTO MessageBoard(MDisplay, MIp, MName, MEmail, MTime, MSaying, MImage) VALUES(1,?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
//随机头像
int i=new Random().nextInt(10);
String muser=new String(request.getParameter("user").getBytes("iso-8859-1"),"utf-8");
String msaying=new String(request.getParameter("saying").getBytes("iso-8859-1"),"utf-8");
//设置参数
ps.setString(1,request.getParameter("sip"));
ps.setString(2,muser);
ps.setString(3,request.getParameter("email"));
ps.setString(4,request.getParameter("stime"));
ps.setString(5,msaying);
ps.setString(6,"img/head"+i+".png");
ps.executeUpdate();
stat.close();
conn.close();
}
%>
<% //获取页数
int pagei=0;
int maxp=0;
if(request.getParameter("page")!=null)
if(request.getParameter("page")!=""){
String str1=request.getParameter("page");
Pattern pattern = Pattern.compile("[0-9]*");
if(pattern.matcher(str1).matches())
pagei=Integer.parseInt(str1);
}
Connection conn = DriverManager.getConnection("jdbc:mysql://url?useUnicode=true&characterEncoding=utf-8",用户名,密码);
Statement stat = conn.createStatement();
//查询总记录数
String sql1 = "SELECT count(MyId) totalCount FROM MessageBoard WHERE MDisplay=1";
ResultSet rset = stat.executeQuery(sql1);
int rowCount = 0;
//获取总记录数
while(rset.next()) {
rowCount=rset.getInt("totalCount");
}
maxp=(rowCount-1)/10;
//计算页数
if((pagei*10+1)>rowCount)
pagei=maxp;
%>
<%
pagei*=10;
%>
<%
// 分页查询 pagei由程序计算生成 不是用户输入 因此不需要参数化
String sql = "SELECT Myid, MName, MTime, MSaying, MImage FROM MessageBoard WHERE MDisplay=1 ORDER BY MTime DESC limit "+pagei+" ,10 ";
ResultSet rs = stat.executeQuery(sql);
//把查询结果先保存下来
List mesIdlist = new ArrayList();
List mesNamelist = new ArrayList();
List mesTimelist = new ArrayList();
List mesSayinglist = new ArrayList();
List mesImglist = new ArrayList();
//打印留言信息
while(rs.next()){
mesIdlist.add(rs.getString("Myid"));
mesNamelist.add(rs.getString("MName"));
mesTimelist.add(rs.getString("MTime"));
mesSayinglist.add(rs.getString("MSaying"));
mesImglist.add(rs.getString("MImage"));
}
for(int ite=0;ite",">");
mesName=mesName.replaceAll("\"",""");
mesName=mesName.replaceAll(" "," ");
String mesHead = mesSaying.substring(0, 1);
String mesLast = mesSaying.substring(1);
mesLast=mesLast.replaceAll("<","<");
mesLast=mesLast.replaceAll(">",">");
mesLast=mesLast.replaceAll("\"",""");
mesLast=mesLast.replaceAll(" "," ");
%>
<%=mesName%>
<%=mesTime%>
<%
// 查询对应留言回复 mesId由程序计算生成 因此不需要参数化
String resql = "SELECT Retext, Rtime FROM ReplyBoard WHERE MyId="+mesId+" ORDER BY Rtime";
ResultSet res = stat.executeQuery(resql);
//打印留言回复
while(res.next()){
String mesReply = res.getString("Retext");
String mesRtime = res.getString("Rtime");
mesReply=mesReply.replaceAll("<","<");
mesReply=mesReply.replaceAll(">",">");
mesReply=mesReply.replaceAll("\"",""");
mesReply=mesReply.replaceAll(" "," ");
%>
Administrator reply: <%=mesReply%>
<%=mesRtime%>
<%
}
%>
<%
}
%>
<%
stat.close();
conn.close();
%>
<%
//分页按钮
if(pagei!=0){
%>
<%
}else{
%>
<%
}
%>
<%=pagei/10+1%>
/
<%=maxp+1%>
<%
if(pagei/10
<%
}else{
%>
<%
}
%>
结果展示:
访客发布和显示页面:
管理员回复页面:
技术要点总结:
1、PreparedStatement参数化传值进行SQL操作,防止恶意用户的SQL注入。
2、分页查询(limit)可减轻数据库的负载以及web页面在传输时所占的带宽。
3、对于提交内容的特殊字符进行转换,以防止HTML或JS攻击。
4、对于中文字符,需要对其进行转码操作。
5、项目大了,纯JSP的页面显然显得过于臃肿,还是建议使用MVC模式或者其他框架模块化编写。