效果图
无留言时的效果
留言的展示
功能
- 留言记录
- 留言删除
- 留言分页
正文
jsp页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ page import="com.service.CommentService" %>
<%@ page import="com.entity.Comment" %>
<%@ page import="java.util.List" %>
<%@ page import="com.service.UserService" %>
<%@ page import="com.myUtil.ProcessUtil" %>
<%@ page import="com.entity.User" %>
<%@ page import="com.myUtil.JdbcUtil" %><%--
Created by IntelliJ IDEA.
User: huawei
Date: 2022/10/15
Time: 21:41
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>留言板</title>
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
<!-- 新 Bootstrap5 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css">
<!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
<script src="https://cdn.staticfile.org/popper.js/2.9.3/umd/popper.min.js"></script>
<!-- 最新的 Bootstrap5 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.min.js"></script>
</head>
<body>
<%--头部导航栏--%>
<nav class="navbar-expand-lg navbar navbar-dark bg-primary">
<div class="container-fluid ">
<a class="navbar-brand" href="#">留言板</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="/MyProject/index.jsp">Home</a>
</li>
</ul>
</div>
</div>
</nav>
<%--留言部分--%>
<div class="container">
<%--留言输入框--%>
<div class="card">
<div class="row">
<div class="contact-box text-center mt-4">
<form action="" method="post">
<div class="form-group row">
<%
UserService userService = new UserService();
String userName = ProcessUtil.getUserNameBySessionId(session);
User user = userService.showDetailInfo(userName);
%>
<div class="form-control-lg col"><input type="text" class="form-control" id="name" name="name"
placeholder="姓名*" required="" disabled="disabled" value="<%=user.getUsername()%>"></div>
<div class="form-control-lg col"><input type="email" class="form-control" id="email" name="email"
placeholder="Email*" required="" disabled="disabled" value="<%=user.getEmail()%>"></div>
</div>
<div class="form-control-lg"><input type="text" class="form-control" id="title" name="title"
placeholder="标题"></div>
<div class="form-control-lg"><textarea class="form-control" id="content" name="content" rows="10"
placeholder="留言内容*" required=""></textarea></div>
<button class="btn btn-primary" type="submit" id="submit">提 交</button>
</form>
</div>
</div>
</div>
<%--留言展示--%>
<%
// 第一次进来默认选择第一页
int pageNum = 1;
String page1 = request.getParameter("page");
// 判断是否是第一次进来
if (page1!=null){
pageNum = Integer.parseInt(page1);
}
CommentService commentService = new CommentService();
List<Comment> comments = commentService.showAllComments();
// JdbcUtil.commit();
List<Comment> pagesComments = commentService.showPagesComments(pageNum);
// JdbcUtil.commit();
request.setAttribute("AllComment",comments);
request.setAttribute("pagesComments",pagesComments);
%>
<c:if test="${empty requestScope.AllComment}">
<div style="width: 500px;" class="text-center m-auto">
<div style="margin-top: 100px">
快来做第一个留言的吧!
</div>
</div>
</c:if>
<c:if test="${!empty requestScope.AllComment}">
<table class="table table-striped">
<tr>
<td>姓名</td>
<td>标题</td>
<td>Email</td>
<td>留言内容</td>
<td>删除</td>
</tr>
<c:forEach items="${requestScope.pagesComments}" var="comment">
<tr>
<td>${comment.name}</td>
<td>${comment.title}</td>
<td>${comment.email}</td>
<td>${comment.content}</td>
<td><button type="submit" class="btn btn-danger" id="delete_${comment.number}">删除</button></td>
</tr>
</c:forEach>
<c:set scope="request" var="count" value="${fn:length(requestScope.AllComment)}"/>
</table>
<nav aria-label="...">
<ul class="pagination justify-content-center" style="margin:20px 0">
<%--获得留言条数--%>
<c:forEach begin="1" end="${(count + 5-1)/5}" var="i">
<li class="page-item"><a class="page-link" href="/MyProject/commentsServlet?method=showPages&page=${i}">${i}</a></li>
</c:forEach>
</ul>
</nav>
</c:if>
</div>
</div>
</body>
</html>
留言的提交
留言提交的js代码
$("#submit").click(
function () {
var name = $("#name").val().trim();
var title = $("#title").val().trim();
var email = $("#email").val().trim();
var content = $("#content").val().trim();
if (name == "" || title == "" || email == "" || content == ""){
}else {
$.post(
"/MyProject/commentsServlet",
{
method: "add",
name: name,
title: title,
email: email,
content: content
},
function (data) {
console.log("成功");
console.log(data.name);
},
"json"
)
}
}
)
留言的提交,我们采用的是发送Ajax请求
。因为普通的表单提交会跳转页面,我们留言是需要页面局部数据的刷新,所以我们使用Ajax
。
关于进行如何分页?
留言板第一次进来,应该获取的第一页也内容(每页显示五条内容),如果超过五条内容就进行分页,这里最关键的分页代码就是${(count + 5-1)/5}
(count是留言的总条数)。这里我们需要注意的就是:在jsp中使用除法,得到的结果是小数,所以我们得到的结果只有小数就向上取整(我们不能进行四舍五入哦)
,这样才能保证分页的正确。
如何进行获取对应页码内容的获取
<li class="page-item">
<a class="page-link" href="/MyProject/commentsServlet?method=showPages&page=${i}">${i}</a>
</li>
我这里采用的是通过参数page
将点击的页码携带过去,在Controller
层进行处理。
如何删除对应的留言
这里我们使用唯一的ID
来标识每一条留言,在点击删除按钮的时候,携带每条留言的唯一ID标识,进而通过JDBC
来删除数据库中的对应ID
的留言数据。
<td>
<button type="submit" class="btn btn-danger" id="delete_${comment.number}">删除</button>
</td>
这里的html的id
是通过数据库中自增留言id
来保证一致性的。
有关删除的js代码
$("button[id^='delete_']").click(
function (e) {
var id = e.target.id;
$.get(
"/MyProject/commentsServlet",
{
method: "delete",
number: id
},
function (data) {
console.log(data);
if(data =="success"){
location.reload(true);
}
},
"json"
)
})
删除同样是局部刷新页面数据,所以前端通过Ajax
向后端发送请求,这里的number
是要删除的当前留言对应的id
。细心的小伙伴可以看出来,这里参数的id
实际上是一个delete_id值
这样的字符串,我这里前面加了 delete_ 是为了标识他的作用。(也没啥大用,在后端通过分割字符串可以处理)
Controller层
package com.controller;
import com.entity.Comment;
import com.google.gson.Gson;
import com.myUtil.JdbcUtil;
import com.service.CommentService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
public class CommentsServlet extends BasicServlet {
private CommentService commentService = new CommentService();
// 删除评论
protected void delete(HttpServletRequest request, HttpServletResponse response){
String number = request.getParameter("number");
if (number!=null){
String[] s = number.split("_");
number = s[1];
try {
commentService.deleteComment(number);
JdbcUtil.commit();
} catch (Exception e) {
JdbcUtil.rollback();
e.printStackTrace();
}
try {
response.getWriter().write(new Gson().toJson("success"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 添加评论
protected void add(HttpServletRequest request, HttpServletResponse response){
String title = request.getParameter("title");
String name = request.getParameter("name");
String email = request.getParameter("email");
String content = request.getParameter("content");
Comment comment = new Comment(null,title, name, email, content);
Boolean aBoolean = null;
try {
aBoolean = commentService.addComment(comment);
JdbcUtil.commit();
} catch (Exception e) {
JdbcUtil.rollback();
}
Gson gson = new Gson();
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
if (aBoolean){
System.out.println("添加成功");
writer.write(gson.toJson("添加成功"));
}else {
System.out.println("添加失败");
writer.write(gson.toJson("添加失败"));
}
}
// 分页显示内容
protected void showPages(HttpServletRequest request, HttpServletResponse response){
String page = request.getParameter("page");
if (page!=null){
int parseInt = Integer.parseInt(page);
List<Comment> comments = null;
try {
comments = commentService.showPagesComments(parseInt);
JdbcUtil.commit();
} catch (Exception e) {
JdbcUtil.rollback();
e.printStackTrace();
}
request.setAttribute("pagesComments",comments);
try {
request.getRequestDispatcher("/comments.jsp").forward(request,response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
service层
package com.service;
import com.dao.CommentDao;
import com.entity.Comment;
import java.util.List;
public class CommentService {
private CommentDao commentDao = new CommentDao();
//添加评论
public Boolean addComment(Comment comment){
return commentDao.addData(comment);
}
//显示所有评论
public List<Comment> showAllComments(){
return commentDao.showAllData();
}
//按页数回显条数
public List<Comment> showPagesComments(int page){
List<Comment> comments = commentDao.showAllData();
if (comments!=null){
if (page > (Math.ceil(comments.size()/5.0))){
page = 1;
}
if (comments!=null && comments.size()!=0){
int start = (page-1) * 5;
int end = (page-1) * 5 + 5;
if(start<comments.size()){
if ((comments.size()-start) < 5){
comments = comments.subList(start,comments.size());
}else {
comments = comments.subList(start,end);
}
}
return comments;
}
}
return null;
}
// 删除评论
public Boolean deleteComment(String number){
return commentDao.deleteData(number);
}
}
Dao层
package com.dao;
import com.entity.Comment;
import java.util.List;
public class CommentDao extends BasicDao<Comment>{
//添加数据
public Boolean addData(Comment comment){
String sql = "INSERT INTO `comments`(`title`,`name`,`email`,`content`) VALUES('" + comment.getTitle() +"','"+ comment.getName() +"','"+ comment.getEmail() +"','"+ comment.getContent()+"')";
return dmlData(sql);
}
//显示所有数据
public List<Comment> showAllData(){
String sql = "SELECT * FROM `comments`";
return queryMulti(sql, Comment.class);
}
// 根据ID删除数据
public Boolean deleteData(String number){
String sql = "DELETE FROM `comments` WHERE `number`=" + number;
return dmlData(sql);
}
}
entity实体类
package com.entity;
public class Comment {
private Integer number;
private String title;
private String name;
private String email;
private String content;
public Comment() {
}
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public Comment(Integer number, String title, String name, String email, String content) {
this.number = number;
this.title = title;
this.name = name;
this.email = email;
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Comment{" +
"number='" + number + '\'' +
", title='" + title + '\'' +
", name='" + name + '\'' +
", email='" + email + '\'' +
", content='" + content + '\'' +
'}';
}
}
comment表设计
列名 | 数据类型 | 长度 | 主键? | 非空? | 自增? | 解释说明 |
---|---|---|---|---|---|---|
number | int | √ | √ | √ | 留言的自增ID,唯一标识每条留言 | |
title | varchar | 32 | √ | √ | 留言的标题 | |
name | varchar | 32 | √ | 留言者的姓名 | ||
varchar | 32 | √ | 留言者的邮箱 | |||
content | varchar | 32 | √ | 留言内容 |