一个jsp+AJAX评论系统

  这是一个简单的评论系统,使用了JDOM(这边使用Jdom-b9),实例使用JSP作为视图,结合使用AJAX(用到prototype-1.4),Servlet和JavaBean作为后台处理,使用xml文件存储数据。

  1.应用目录结构如下:

  data

  |--comment.xml

  js

  |--prototype.js

  |--ufo.js(UTF-8格式)

  css

  |--ufo.css

  images

  |--loading.gif

  ufo.jsp(UTF-8格式)

  WEB-INF

  |-lib

  |-jdom.jar

  |-classes

  ...

  |-web.xml

  /*********************************************

  *Author:Java619

  *Time:2007-02-14

  **********************************************/

  2.后台JavaBean  CommentBean.java

  /** *//**

  * <P>外星人是否存在评论系统</p>

  * @author ceun

  * 联系作者:<br>

  *    <a href="mailto:[email protected]">ceun</a><br>

  * @version 1.0 2007-01-30 实现基本功能<br>

  * CommentBean.java

  * Created on Jan 30, 2007 9:39:19 AM

  */

  package com.ceun.bean;

  import java.io.FileWriter;

  import java.io.IOException;

  import java.text.SimpleDateFormat;

  import java.util.ArrayList;

  import java.util.Date;

  import java.util.List;

  import java.util.Random;

  import org.jdom.CDATA;

  import org.jdom.Document;

  import org.jdom.Element;

  import org.jdom.JDOMException;

  import org.jdom.Text;

  import org.jdom.input.SAXBuilder;

  import org.jdom.output.XMLOutputter;

  /** *//**

  *<p> 封装对XML的操作</p>

  * @author ceun

  * 联系作者:<br>

  *    <a href="mailto:[email protected]">ceun</a><br>

  * @version 1.0 2007-01-30 实现基本功能<br>

  */

  public class CommentBean ...{

  private String filepath;

  private SAXBuilder builder = null;

  private Document doc = null;

  public CommentBean() ...{

  }

  /** *//**

  * 初始化XML文件路径,加载文件

  * */

  public CommentBean(String path) ...{

  this.filepath = path;

  builder = new SAXBuilder();

  try ...{

  doc = builder.build(filepath);

  } catch (JDOMException e) ...{

  System.out.print("找不到指定的XML文件");

  e.printStackTrace();

  } catch (IOException e) ...{

  System.out.print("找不到指定的文件");

  e.printStackTrace();

  }

  }

  /** *//**

  * 添加评论

  * @param nikename 评论者昵称

  * @param comment 评论内容

  * @param attitude 评论者的结论(yes-存在,no-不存在)

  * */

  public String addComment(String nikename, String comment, String attitude) ...{

  Element root = doc.getRootElement();

  Element el = new Element("comment");

  Random rand = new Random();

  int id = rand.nextInt(10000);

  el.setAttribute("id", "comment_" + id);

  el.setAttribute("attitude", attitude);

  Element name = new Element("nikename");

  CDATA cname = new CDATA(nikename);

  name.addContent(cname);

  Element data = new Element("data");

  CDATA ctext = new CDATA(comment);

  data.addContent(ctext);

  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

  Date date = new Date();

  Text tdate = new Text(format.format(date));

  Element pubdate = new Element("pubdate");

  pubdate.addContent(tdate);

  el.addContent(name);

  el.addContent(data);

  el.addContent(pubdate);

  root.addContent(el);

  XMLOutputter outputter = new XMLOutputter("  ", true, "GB2312");

  // 清除comment元素间的空格

  outputter.setTrimAllWhite(true);

  try ...{

  outputter.output(doc, new FileWriter(filepath));

  } catch (IOException e) ...{

  System.out.println("指定路径有错");

  e.printStackTrace();

  }

  return tdate.getText();

  }

  /** *//**

  * 删除指定ID的评论

  * @param commentId 评论ID

  * @return 返回操作结果字符串(成功或失败)

  * */

  public String removeComment(String commentId) ...{

  Element root = doc.getRootElement();

  List comments = root.getChildren();

  int size = comments.size();

  Element dist = null;

  for (int i = 0; i < size; i++) ...{

  Element comment = (Element) comments.get(i);

  String id = comment.getAttributeValue("id");

  if (id.equals(commentId)) ...{

  dist = comment;

  break;

  }

  }

  if (dist != null) ...{

  root.removeContent(dist);

  XMLOutputter outputter = new XMLOutputter("  ", true, "GB2312");

  // 清除comment元素间的空格

  outputter.setTrimAllWhite(true);

  try ...{

  outputter.output(doc, new FileWriter(filepath));

  } catch (IOException e) ...{

  System.out.println("重写文件有出错");

  e.printStackTrace();

  }

  return "成功删除指定元素!";

  } else

  return "指定元素不存在!";

  }

  /** *//**

  * 批量删除评论

  * @param commentIdArgs 评论ID数组

  * @return 返回操作结果字符串(成功或失败)

  * */

  public String removeComments(String[] commentIdArgs) ...{

  Element root = doc.getRootElement();

  List comments = root.getChildren();

  int size = comments.size();

  int len = commentIdArgs.length;

  List<Element> dist = new ArrayList<Element>();

  outer:for (int i = 0; i < size; i++) ...{

  Element comment = (Element) comments.get(i);

  String id = comment.getAttributeValue("id");

  for (int j = 0; j < len; j++)

  if (id.equals(commentIdArgs[j])) ...{

  dist.add(comment);

  continue outer;

  }

  }

  int dist_size=dist.size();

  if (dist_size != 0) ...{

  for (int i = 0; i < dist_size; i++)

  root.removeContent(dist.get(i));

  XMLOutputter outputter = new XMLOutputter("  ", true, "GB2312");

  // 清除comment元素间的空格

  outputter.setTrimAllWhite(true);

  try ...{

  outputter.output(doc, new FileWriter(filepath));

  } catch (IOException e) ...{

  System.out.println("重写文件有出错");

  e.printStackTrace();

  }

  return "成功删除指定的元素集合!";

  } else

  return "指定元素集合的不存在!";

  }

  /** *//**

  * @return the filepath

  */

  public String getFilepath() ...{

  return filepath;

  }

  /** *//**

  * @param filepath

  *            the filepath to set

  */

  public void setFilepath(String filepath) ...{

  this.filepath = filepath;

  }

  /** *//**

  * @return the builder

  */

  public SAXBuilder getBuilder() ...{

  return builder;

  }

  /** *//**

  * @param builder

  *            the builder to set

  */

  public void setBuilder(SAXBuilder builder) ...{

  this.builder = builder;

  }

  }

  3.处理AJAX请求的Servlet  AddCommentServlet.java

  package com.ceun.servlet;

  import java.io.IOException;

  import java.io.PrintWriter;

  import javax.servlet.ServletException;

  import javax.servlet.http.HttpServlet;

  import javax.servlet.http.HttpServletRequest;

  import javax.servlet.http.HttpServletResponse;

  import com.ceun.bean.CommentBean;

  /** *//**

  * <p>后台处理Servlet</p>

  *2007-01-30

  * * @author ceun

  * 联系作者:<br>

  *    <a href="mailto:[email protected]">ceun</a><br>

  * @version 1.0 2007-01-30 实现基本功能<br>

  * */

  public class AddCommentServlet extends HttpServlet ...{

  /** *//**

  * serialVersionUID long

  */

  private static final long serialVersionUID = 1L;

  /** *//**

  * The doGet method of the servlet. <br>

  *

  * This method is called when a form has its tag value method equals to get.

  *

  * @param request

  *            the request send by the client to the server

  * @param response

  *            the response send by the server to the client

  * @throws ServletException

  *             if an error occurred

  * @throws IOException

  *             if an error occurred

  */

  public void doGet(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException ...{

  request.setCharacterEncoding("UTF-8");

  response.setContentType("text/html;charset=UTF-8");

  response.setHeader("Cache-Control", "no-cache");

  PrintWriter out = response.getWriter();

  String nikename = request.getParameter("nn");

  String comment = request.getParameter("rsn");

  String attitude = request.getParameter("atti");

  String filepath = request.getSession().getServletContext().getRealPath(

  "data/comment.xml");

  CommentBean bean = new CommentBean(filepath);

  String str = bean.addComment(nikename, comment, attitude);

  out.println(str);

  }

  /** *//**

  * The doPost method of the servlet. <br>

  *

  * This method is called when a form has its tag value method equals to

  * post.

  *

  * @param request

  *            the request send by the client to the server

  * @param response

  *            the response send by the server to the client

  * @throws ServletException

  *             if an error occurred

  * @throws IOException

  *             if an error occurred

  */

  public void doPost(HttpServletRequest request, HttpServletResponse response)

  throws ServletException, IOException ...{

  doGet(request, response);

  }

  }

  4.JSP视图 ufo.jsp

  <%...@ page contentType="text/html;charset=UTF-8"%>

  <%...

  String path = request.getContextPath();

  String basePath = request.getScheme() + "://"

  + request.getServerName() + ":" + request.getServerPort()

  + path + "/";

  %>

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh_CN" lang="zh_CN">

  <head>

  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <meta http-equiv="pragma" content="no-cache" />

  <meta http-equiv="cache-control" content="no-cache" />

  <meta http-equiv="expires" content="0" />

  <title>ufo</title>

  <link rel="stylesheet" type="text/css" href="css/ufo.css"/>

  <script src="<%=basePath%>js/prototype.js" type="text/javascript"></script>

  <script src="<%=basePath%>js/ufo.js" type="text/javascript"></script>

  </head>

  <SCRIPT type="text/javascript">...

  <!--

  window.onload=function()...{

  getComments("<%=basePath%>data/comment.xml");

  }

  //-->

  </SCRIPT>

  <body>

  <div id="cinfoDiv" style="display:none;">

  <h2>

  信息提示

  </h2>

  <p id="cinfomsg">

  </p>

  </div>

  <table id="process-indicator"

  style="display:none;z-index:100;width:300px;">

  <tr>

  <td>

  <img src="images/loading.gif" />

  <p>

  正在处理中...

  </p>

  </td>

  </tr>

  </table>

  <center>

  <div id="comment-lists">

  </div>

  <div id="comment">

  <div style="display:none;top:100px;left:200px;" id="locateDiv1">

  </div>

  <div id="comment-bar">

  你认为外星人存在吗?

  </div>

  <div id="comment-form">

  <form onsubmit="return false;" name="cform">

  昵称:

  <input type="text" id="nn" name="nn" />

  <input type="radio" id="exist" name="exist" value="yes" />

  存在

  <input type="radio" id="exist" name="exist" value="no" />

  不存在

  <br />

  <textarea name="reason" style="width: 480px;height:200px;"

  id="reason"></textarea>

  <button id="btnsubmit" class="button"

  onclick="addComment('<%=path%>/addCommentServlet');">

  发表你的看法

  </button>

  <input type="reset" id="btnreset" class="button" />

  </form>

  </div>

  </div>

  </center>

  </body>

  </html>

  5.前台脚本 ufo.js

  var Browser = ...{};

  Browser.isMozilla = (typeof document.implementation !=

  "undefined") && (typeof document.implementation.createDocument != "undefined") && (typeof HTMLDocument != "undefined");

  Browser.isIE = window.ActiveXObject ? true : false;

  Browser.isFirefox = (navigator.userAgent.toLowerCase().indexOf("firefox") != -1);

  Browser.isSafari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);

  Browser.isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);

  String.prototype.trim=function()...{return this.replace(/^s+|s+$/g,"");};

  function addComment(url)...{

  var nn=$F("nn");

  var rsn=$F("reason");

  var atti=false;

  var rbgroup=document.cform.elements["exist"];

  for(i=0;i<rbgroup.length;i++)...{

  if(rbgroup[i].checked) ...{atti=rbgroup[i].value;break;};

  }

  var locateTop=$("locateDiv1").parentNode.offsetTop-50;

  var locateLeft=$("locateDiv1").parentNode.offsetLeft+150;

  var alertMsg="";

  if(!atti)

  alertMsg+="<br/>请表明你的态度!";

  if(nn.trim()=="")

  alertMsg+="<br/>昵称不能为空!"

  if(rsn.trim()=="")

  alertMsg+="<br/>请写下你的理由!";

  var cinfomsg=$("cinfomsg");

  if(alertMsg!="")...{

  cinfomsg.className="failure";

  cinfomsg.innerHTML=alertMsg;

  showDialog($("cinfoDiv"),locateTop,locateLeft);

  return;

  }else...{

  cinfomsg.className="success";

  cinfomsg.innerHTML="正处理数据中...";

  showDialog($("cinfoDiv"),locateTop,locateLeft);

  }

  var pars="nn="+nn+"&atti="+atti+"&rsn="+rsn;

  var http=Ajax.getTransport();

  var contentType = "application/x-www-form-urlencoded; charset=utf-8";

  http.open("POST",url,true);

  http.setRequestHeader("Content-Type", contentType);

  http.onreadystatechange=function()...{

  if (http.readyState == 4)...{

  if (http.status==200)...{

  afterAdd(http);

  }

  }

  }

  http.send(pars);

  }

  function afterAdd(request)...{

  hideDialog();

  var atti=false;

  var rbgroup=document.cform.elements["exist"];

  for(i=0;i<rbgroup.length;i++)...{

  if(rbgroup[i].checked) ...{atti=rbgroup[i].value;break;};

  }

  var nn=$F("nn");

  var rsn=$F("reason");

  generateCommentList(atti,nn,request.responseText,rsn)

  $("nn").value="";

  $("reason").value="";

  }

  function generateCommentList(atti,nn,date,rsn)...{

  var commentLists=$("comment-lists");

  var commentlist=document.createElement("div");

  commentlist.className="comment-list";

  var observerInfo=document.createElement("div");

  observerInfo.className="observer-info";

  var attitude=(atti=="yes")?"认为存在":"认为不存在";

  var info=document.createTextNode("评论者:"+nn+" 观点:"+attitude+" "+date);

  observerInfo.appendChild(info);

  var observerComment=document.createElement("div");

  observerComment.className="observer-comment";

  var reason=document.createTextNode(rsn);

  observerComment.appendChild(reason);

  commentlist.appendChild(observerInfo);

  commentlist.appendChild(observerComment);

  if(commentLists.hasChildNodes())...{

  var tmp=commentLists.firstChild;

  commentLists.insertBefore(commentlist,tmp);

  }else

  commentLists.appendChild(commentlist);

  }

  function getComments(url)...{

  Element.show("process-indicator");

  Element.makePositioned("process-indicator");

  var top = document.body.scrollTop + 200;

  var left = "";

  if ($("process-indicator").style.width) ...{

  left =window.document.body.scrollWidth/2-100;

  } else ...{

  left = parseInt(document.body.clientWidth / 2);

  }

  var style = ...{top:top + "px", left:left + "px"};

  Element.setStyle("process-indicator", style);

  //加个随机数,去除缓存影响

  var pars="rd=rd_"+parseInt(Math.random()*10000);

  var http=Ajax.getTransport();

  var contentType = "application/x-www-form-urlencoded; charset=utf-8";

  http.open("POST",url,true);

  http.setRequestHeader("Content-Type", contentType);

  http.onreadystatechange=function()...{

  if (http.readyState == 4)...{

  if (http.status==200)...{

  afterGetComments(http);

  }

  }

  }

  http.send(pars);

  }

  function afterGetComments(request)...{

  //提示框

  Element.hide("process-indicator");

  var xmldata=request.responseXML;

  var comments=xmldata.getElementsByTagName("comment");

  if(!comments)...{alert("暂无评论");return;}

  var len=comments.length;

  for(var i=0;i<len;i++)...{

  var atti=comments[i].getAttribute("attitude");

  var nn=comments[i].getElementsByTagName("nikename")[0].firstChild.nodeValue;

  var rsn=comments[i].getElementsByTagName("data")[0].firstChild.nodeValue;

  var date=comments[i].getElementsByTagName("pubdate")[0].firstChild.nodeValue;

  generateCommentList(atti,nn,date,rsn)

  }

  }

  //对话框模块

  var lastDialog=null;

  function showDialog(dialog,offsetTop,offsetLeft)...{

  if (lastDialog) lastDialog.style.display="none";

  dialog.style.top=offsetTop+"px";

  dialog.style.left=offsetLeft+"px";

  dialog.style.display="";

  lastDialog=dialog;

  document.onmousedown=toHideDialog

  }

  function toHideDialog(event)...{

  if (!lastDialog) ...{document.onclick=null;return;}

  var obj=null;

  if(Browser.isIE) obj=window.event.srcElement;

  else obj=event.target;

  hideDialog();

  }

  function hideDialog()...{

  if (lastDialog) lastDialog.style.display="none";

  lastDialog=null

  document.onmousedown=null;

  }

  6.CSS ufo.css

  #comment{...}{

  background-color: InactiveCaptionText;

  width: 550px;

  height:300px;

  margin-top:10px;

  }

  #comment-bar{...}{

  color:white;

  padding-top: 5px;

  padding-bottom: 5px;

  text-align: center;

  background-color: ActiveCaption;

  }

  #comment-form{...}{

  padding-left:20px;

  }

  .button{...}{

  BORDER-RIGHT: #283043 1px solid; PADDING-RIGHT: 1px; BORDER-TOP: #9097a2 1px solid;

  PADDING-LEFT: 1px; BACKGROUND: ActiveCaption;; PADDING-BOTTOM: 1px;

  BORDER-LEFT: #9097a2 1px solid; COLOR: #fff;

  PADDING-TOP: 1px; BORDER-BOTTOM: #283043 1px solid;

  margin: 10px;

  }

  #comment-lists{...}{

  background-color: InactiveCaptionText;

  width: 550px;

  margin-bottom:10px;

  }

  div.comment-list{...}{

  text-align: left;

  border:1px solid ActiveCaption;

  margin: 5px;

  }

  div.observer-info{...}{

  color:white;

  padding-top: 5px;

  padding-bottom: 5px;

  padding-left: 5px;

  text-align: left;

  background-color: ActiveCaption;

  font-size: 14px;

  }

  div.observer-comment{...}{

  padding-top: 5px;

  padding-bottom: 5px;

  text-align: left;

  }

  #process-indicator{...}{

  margin:10px;padding-top:15px;padding-right:5px;padding-left:5px;

  background-color:cyan;position:absolute;border:2px solid ActiveCaption;

  }

  .success {...}{

  COLOR: Blue;

  }

  .failure {...}{

  COLOR: #ff665b

  }

  #cinfoDiv {...}{

  position:absolute;

  top:10px;

  width:200px;

  height:120px;

  z-index:1000;

  background-color:#F0F8FF;

  border:1px solid #009999

  }

  #cinfoDiv h2{...}{

  background-color:#483D8B;

  font-size:14px;

  color:#fff;

  text-align:center;

  margin-top:0px;

  }

  #cinfoDiv p{...}{

  margin:5px;

  text-align:center;

  vertical-align: top;

  font-size:14px;

  }

  7.comment.xml

  <?xml version="1.0" encoding="GB2312"?>

  <comments>

  <comment id="comment_4119" attitude="yes">

  <nikename><![CDATA[薜荔女萝衣]]></nikename>

  <data><![CDATA[这个问题要全面分析。

  外星很简单,相对于地球之外而言。

  人吗,就给这个生物一个限定性标准了,至少要像人啊。

  存在本身就是一个问题。谁能证明存在是存在的呢?

  谁又能全面地证明存在是不存在的呢?类似高尔吉亚的智者派的方法就不要再用了。

  之后才要探讨是与否的问题。

  ]]></data>

  <pubdate>2007-01-31 20:53:33</pubdate>

  </comment>

  <comment id="comment_5953" attitude="yes">

  <nikename><![CDATA[ぁあ宇宙过客]]></nikename>

  <data><![CDATA[肯定会存在,难道真么大一个宇宙就只有地球有生物?

  ]]></data>

  <pubdate>2007-01-31 20:56:17</pubdate>

  </comment>

  <comment id="comment_2199" attitude="yes">

  <nikename><![CDATA[匿名]]></nikename>

  <data><![CDATA[存在。如果没有的话怎么会在恐龙的肚子中找到一个相似外星化石呢?]]></data>

  <pubdate>2007-01-31 21:00:43</pubdate>

  </comment>

  <comment id="comment_8637" attitude="yes">

  <nikename><![CDATA[互相帮助小组]]></nikename>

  <data><![CDATA[有高等智慧生物吧,但不一定是人的形势啊!我坚信它们的存在。]]></data>

  <pubdate>2007-01-31 21:03:21</pubdate>

  </comment>

  <comment id="comment_237" attitude="yes">

  <nikename><![CDATA[秦国园林]]></nikename>

  <data><![CDATA[我就是外星人,我乘坐的大型飞行器----地球,不知什么时侯回到我的家乡----宇宙的起点.

  自从人类产生就和那失去了联系,你能告诉我航行的方向吗?船长先生.

  ]]></data>

  <pubdate>2007-01-31 21:11:06</pubdate>

  </comment>

  </comments>