使用SSM框架实现留言回复功能(基于MySQL) 之前一直纠结这个留言回复功能怎么写,在网上也没有找到一个明确的案例,这里我简单介绍一下我写的基于MySQL的留言回复功能。
注意:首先使用MySQL数据库存放留言回复信息并不是首选,听大佬说过使用RabbitMQ
消息组件,但是我没有学过,暂不清楚。 对于我此次写的留言回复功能仍有缺陷,大家可以留意一下QQ空间中的留言回复功能,我这里并没有实现那种效果。如果大家有好的方案欢迎联系告知我。
<!--more-->
本项目源码:GitHub
首先我们看一下效果图
创建表结构
留言表(Words)
create table words(
#留言id编号
lw_id int primary key auto_increment,
#留言人的名字
lw_name varchar(100),
#留言日期
lw_date varchar(100),
#留言内容
lw_content varchar(100),
#给谁留言
lw_for_name varchar(100),
#在哪篇文章下留言
lw_for_article_id varchar(100)
)default charset = utf8;
回复表(Reply)
create table reply(
#回复id编号
lr_id int primary key auto_increment,
#回复人名字
lr_name varchar(100),
#回复时间
lr_date varchar(100),
#回复内容
lr_content varchar(100),
#给谁回复
lr_for_name varchar(100),
#在哪个留言下的回复
lr_for_words varchar(100),
#在哪篇文章下的回复
lr_for_article_id varchar(100)
)default charset = utf8;
以上是我实现留言回复功能所建的两张表,创建完表结构,让我们分析一下怎么实现留言回复功能:
功能实现
设计思路
如下图所示:
上图中已展示了大概的思路,后端仅仅简单的查询和保存留言回复的信息。JSP使用<c:foreach>遍历后端查询到List集合数据, 使用<c:if>进行判断此条信息是否该放到该篇文章下。详细代码如下:
JSP层
页面使用的layui进行的美化
<!-- 留言的表单 -->
<form class="layui-form" action="<%=basePath%>/article/saveWords.do" method="post" style="width:80%;">
<input name="lw_name" value="${sessionScope.name}" hidden="hidden"/>
<input name="lw_date" value="<%=nowDate%>" hidden="hidden"/>
<input name="lw_for_article_id" value="${article.r_id}" hidden="hidden"/>
<div class="layui-input-block" style="margin-left: 0;">
<textarea id="lw_content" name="lw_content" placeholder="请输入你的留言" class="layui-textarea" style="height: 150px;"></textarea>
</div>
<br/>
<div class="layui-input-block" style="text-align: left;margin-left: 0;">
<input type="submit" class="layui-btn" value="留言">
</div>
</form>
<br/>
<!-- 留言信息列表展示 -->
<div>
<ul>
<!-- 先遍历留言信息(一条留言信息,下面的全是回复信息) -->
<c:forEach items="${requestScope.lw_list}" var="words">
<!-- 如果留言信息是在本文章下的才显示 -->
<c:if test="${words.lw_for_article_id eq article.r_id}">
<li style="border-top: 1px dotted #01AAED">
<br/>
<div style="text-align: left;color:#444">
<div>
<span style="color:#01AAED">${words.lw_name}</span>
</div>
<div>${words.lw_content}</div>
</div>
<div>
<div class="comment-parent" style="text-align:left;margin-top:7px;color:#444">
<span>${words.lw_date}</span>
<p>
<a href="javascript:;" style="text-decoration: none;" onclick="btnReplyClick(this)">回复</a>
</p>
<hr style="margin-top: 7px;"/>
</div>
<!-- 回复表单默认隐藏 -->
<div class="replycontainer layui-hide" style="margin-left: 61px;">
<form action="<%=basePath%>/article/saveReply.do" method="post" class="layui-form">
<input name="lr_for_article_id" id="lr_for_article_id" value="${article.r_id}" hidden="hidden"/>
<input name="lr_name" id="lr_name" value="${sessionScope.name}" hidden="hidden"/>
<input name="lr_date" id="lr_date" value="<%=nowDate%>" hidden="hidden"/>
<input name="lr_for_name" id="lr_for_name" value="${words.lw_name}" hidden="hidden"/>
<input name="lr_for_words" id="lr_for_words" value="${words.lw_id}" hidden="hidden"/>
<input name="lr_for_reply" id="lr_for_reply" value="${reply.lr_id}" hidden="hidden"/>
<div class="layui-form-item">
<textarea name="lr_content" id="lr_content" lay-verify="replyContent" placeholder="请输入回复内容" class="layui-textarea" style="min-height:80px;"></textarea>
</div>
<div class="layui-form-item">
<button id="replyBtn" class="layui-btn layui-btn-mini" lay-submit="formReply" lay-filter="formReply">提交</button>
</div>
</form>
</div>
</div>
<!-- 以下是回复信息 -->
<c:forEach items="${requestScope.lr_list}" var="reply">
<!-- 每次遍历出来的留言下存在回复信息才展示(本条回复信息是本条留言下的就显示在当前留言下) -->
<c:if test="${reply.lr_for_article_id eq article.r_id && reply.lr_for_words eq words.lw_id}">
<div style="text-align: left;margin-left:61px;color: #444">
<div>
<span style="color:#5FB878">${reply.lr_name} </span>
</div>
<div>${reply.lr_content}</div>
</div>
<div>
<div class="comment-parent" style="text-align:left;margin-top:7px;margin-left:61px;color:#444">
<span>${reply.lr_date}</span>
<p>
<a href="javascript:;" style="text-decoration: none;" onclick="btnReplyClick(this)">回复</a>
</p>
<hr style="margin-top: 7px;"/>
</div>
<!-- 回复表单默认隐藏 -->
<div class="replycontainer layui-hide" style="margin-left: 61px;">
<form action="<%=basePath%>/article/saveReply.do" method="post" class="layui-form">
<input name="lr_for_article_id" id="lr_for_article_id" value="${article.r_id}" hidden="hidden"/>
<input name="lr_name" id="lr_name" value="${sessionScope.name}" hidden="hidden"/>
<input name="lr_date" id="lr_date" value="<%=nowDate%>" hidden="hidden"/>
<input name="lr_for_name" id="lr_for_name" value="${words.lw_name}" hidden="hidden"/>
<input name="lr_for_words" id="lr_for_words" value="${words.lw_id}" hidden="hidden"/>
<input name="lr_for_reply" id="lr_for_reply" value="${reply.lr_id}" hidden="hidden"/>
<div class="layui-form-item">
<textarea name="lr_content" id="lr_content" lay-verify="replyContent" placeholder="请输入回复内容" class="layui-textarea" style="min-height:80px;"></textarea>
</div>
<div class="layui-form-item">
<button id="replyBtn" class="layui-btn layui-btn-mini" lay-submit="formReply" lay-filter="formReply">提交</button>
</div>
</form>
</div>
</div>
</c:if>
</c:forEach>
</li>
</c:if>
</c:forEach>
</ul>
</div>
js代码
保存回复信息使用的ajax提交的表单,如上文中介绍,页面一共存在两个表单,一个是每篇文章都会显示的留言框;第二个是当存在留言时会显示的一个回复按钮, 点击回复,就会将隐藏的回复表单显示出来(使用JQuery)
<script type="text/javascript">
function btnReplyClick(elem) {
var $ = layui.jquery;
$(elem).parent('p').parent('.comment-parent').siblings('.replycontainer').toggleClass('layui-hide');
if ($(elem).text() == '回复') {
$(elem).text('收起')
} else {
$(elem).text('回复')
}
}
$("#replyBtn").click(function(){
var lr_for_article_id = $("#lr_for_article_id").val();
var lr_name = $("#lr_name").val();
var lr_date = $("#lr_date").val();
var lr_for_name = $("#lr_for_name").val();
var lr_content = $("#lr_content").val();
var lr_for_words = $("#lr_for_words").val();
$.ajax({
url: '<%=basePath%>/article/saveReply.do',
type: 'POST',
data: [{
lr_for_article_id: lr_for_article_id,
lr_name: lr_name,
lr_date: lr_date,
lr_for_name: lr_for_name,
lr_content: lr_content,
lr_for_words: lr_for_words
}],
success: function(data){
layer.open({
title: '提示信息',
content: '留言成功',
btn: ['确定'],
btn1: function(index){
$("body").html(data);
}
});
},
error: function(){
layer.open({
title: '提示信息',
content: '出现未知错误'
});
}
});
});
</script>
Controller层
/**
* 保存留言信息
*/
@RequestMapping(value="/saveWords")
public String saveWords(Words words){
if(words != null){
String r_id = words.getLw_for_article_id();
articleService.saveWords(words);
return "redirect:toArticleView.do?r_id="+r_id;
}else{
return null;
}
}
/**
* 保存回复信息
*/
@RequestMapping(value="/saveReply")
public String saveReply(Reply reply){
if(reply != null){
articleService.saveReply(reply);
String r_id = reply.getLr_for_article_id();
return "redirect:toArticleView.do?r_id="+r_id;
}else{
return null;
}
}
/**
* 跳转到查看文章内容页面
*/
//声明用于存放留言回复信息的List集合
private List<Words> lw_list;
private List<Reply> lr_list;
@RequestMapping(value="/toArticleView")
public String toArticleView(@RequestParam int r_id, Model model){
//封装留言信息
lw_list = articleService.findByWords();
model.addAttribute("lw_list",lw_list);
//封装回复信息
lr_list = articleService.findByReply();
model.addAttribute("lr_list",lr_list);
//查询文章信息
Article article = articleService.findById(r_id);
System.out.println("查询到当前文章的ID值:"+article.getR_id());
if (article != null) {
model.addAttribute("article", article);
return "view/article/articleView";
} else {
return null;
}
}
综上
主要的代码如上文所写,并不复杂,但是没有实现类似QQ空间的那种回复效果,原因就是jsp使用的EL表达式进行遍历后端储存在域对象中的List集合对象,而这种遍历是依次遍历的,后遍历出来的回复信息需要和之前已经遍历出来的留言信息进行比较判断,如果此回复是属于该留言的才显示,就是因为顺序遍历,之前遍历的数据又该怎么在后面取得呢?如果大家有更好的方案,欢迎联系我。
<hr/>
交流
如果大家有兴趣,欢迎大家加入我的Java交流群:671017003 ,一起交流学习Java技术。博主目前一直在自学JAVA中,技术有限,如果可以,会尽力给大家提供一些帮助,或是一些学习方法,当然群里的大佬都会积极给新手答疑的。所以,别犹豫,快来加入我们吧!
<br/>
联系
If you have some questions after you see this article, you can contact me or you can find some info by clicking these links.
- [Blog@TyCoding's blog](http://www.tycoding.cn)
- [GitHub@TyCoding](https://github.com/TyCoding)
- [ZhiHu@TyCoding](https://www.zhihu.com/people/tomo-83-82/activities)
<br/>