【JavaEE】进阶 · 个人博客系统(5)
文章目录
- 【JavaEE】进阶 · 个人博客系统(5)
- 1. 预期效果
- 2. 约定前后端交互接口
- 3. 分页原理
- 4. 后端代码
- 5. 前端代码
- 6. 测试
- 7. 补充
后端:
前端:
后端只要知道页码和一页多少条数据,就可以计算出要选取哪几条数据(发送期间博客表发生改变而有偏差,这无所谓,很正常,无关紧要的事)
psize
=> 一页的限制,就是limit
后面的值
pindex
页前有多少条数据,就是偏移量 => psize × (pindex - 1)
=> 页就是 offset
后面的值
所有博客数 / psize
,向上取整就是最大页码pMax
,如果所有博客数为0,则前端应该显示 当前在第0页,共0页
pindex的正确性,正常情况下是不会错误的,因为前端知道最大页码pMax
,则不会继续翻下一页~
pMax < pindex
的异常情况就行了~psize
过大则无所谓,大不了一整页显示所有的数据@RequestMapping("/all_list")
public CommonResult allList(@RequestParam("pindex") Integer pindex, @RequestParam("psize") Integer psize, HttpServletRequest request) throws ExecutionException, InterruptedException {
// 1. 校验参数
if(pindex == null || pindex < 1) {
pindex = 1;//页码
}
if(psize == null || psize < 2) {
psize = 2;//页内博客数
}
// 2. 并发进行文章列表和总页数的查询
Integer index = pindex;
Integer size = psize;
FutureTask<List<ArticleInfo>> task1 = new FutureTask<List<ArticleInfo>>(() -> {
int offset = size * (index - 1);
return articleService.getSubList(size, offset);
});
FutureTask<Integer> task2 = new FutureTask<Integer>(() -> {
return articleService.getNumber();
});
APPUtils.THREAD_POOL.submit(task1);
APPUtils.THREAD_POOL.submit(task2);
//因为数据库的一条语句是保证原子性的,所以线程安全
// 3. 数据进一步处理
int count = task2.get();
int pMax = (int)Math.ceil(count * 1.0 / size);
if(pMax != 0 && index > pMax) {
return CommonResult.fail(-2, "并不存在第" + index + "页,目前正在返回首页!");
}
List<ArticleInfo> list = task1.get();
ArticleUtils.substringList(list);
// 4. 构造数据并返回
Map<String, Object> map = new HashMap<>();
map.put("login", SessionUtils.getUser(request) != null);
map.put("list", list);
map.put("pMax", pMax);
return CommonResult.success(map);
}
public List<ArticleInfo> getSubList(int limit, int offset) {
return articleMapper.getSubList(limit, offset);
}
public int getNumber() {
return articleMapper.getNumber();
}
@Select("select * from articleinfo order by id desc limit #{limit} offset #{offset}")
List<ArticleInfo> getSubList(@Param("limit") int limit, @Param("offset") int offset);
@Select("select count(*) from articleinfo")
int getNumber();
.excludePathPatterns("/art/all_list")
- 导航栏
- 页面主体
- 翻页器css属性
.blog-pagnation-wrapper { background-color: rgba(255, 255, 255, 0.8); height: 40px; margin: 16px 0; border-radius: 5px; display: flex; justify-content: center; align-items: center; } .blog-pagnation-item { display: inline-block; padding: 8px; border: 1px solid #d0d0d5; color: #333; } .blog-pagnation-item:hover { background: rgb(252, 133, 167); color: #fff; } .blog-pagnation-item.actvie { background: rgb(252, 133, 167); color: #fff; }
<script>
var psize = 2;
var pindex = 1;
// 初始化数据
function init() {
// 1. 得到url的分页相关的参数
psize = getParamValue("psize");
pindex = getParamValue("pindex");
if (psize == null || parseInt(psize) == NaN || psize < 2) {
psize = 2;
}
if (pindex == null || parseInt(pindex) == NaN || pindex < 1) {
pindex = 1;
}
// 2. 发送请求(psize pindex)
jQuery.ajax({
url: "/art/all_list?psize=" + psize + "&pindex=" + pindex,
method: "get",
success: function (body) {
if (body.code == 200) {
// 3. 导航栏显示
if (body.data.login == false) {
jQuery("#icon").attr("href", "img/logo2.png");
jQuery(".navigation img").attr("src", " img/logo2.png");
jQuery(".navigation .space").css("width", "75%");
jQuery(".title").text("未登录");
jQuery("#mine").hide();
jQuery("#add").hide();
jQuery("#logout").text("登录");
jQuery("#logout").attr("href", "blog_login.html");
}
// 4. 显示文章,构造博客html元素
if (body.data.list.length == 0) {
jQuery(".article").append(
jQuery('暂无文章
')
);
jQuery("#tip").text(
"(当前在第 " + 0 + " 页,共 " + 0 + " 页)"
); //一页为0,只有在没有一条数据的时候才会出现!
return 0;
}
jQuery("#tip").text(
"(当前在第 " + pindex + " 页,共 " + body.data.pMax + " 页)"
);
jQuery("#pmax").val(body.data.pMax);
for (var blog of body.data.list) {
var art = '';
art += '';
art += '+ blog.photo + '"/>';
art += '' + blog.title + "";
art +=
'' +
blog.createtime +
" 阅读量:" +
blog.rcount +
"";
art += '' + blog.summary + "";
art +=
'+ blog.id + '">查看正文';
art += "";
jQuery(".article").append(jQuery(art));
}
} else if (body.code == -2) {
alert(body.msg);
location.href = "blog_lists.html?pindex=1&psize=" + psize;
} else {
alert("查看失败:" + body.msg);
}
},
});
}
init();
function tofirst() {
if (pindex == 1) {
alert("已在首页!");
location.href = location.href;
} else {
location.href = "blog_lists.html?pindex=1&psize=" + psize;
}
}
function toLast() {
if (pindex == jQuery("#pmax").val()) {
alert("已在末页!");
location.href = location.href;
} else {
location.href =
"blog_lists.html?pindex=" +
jQuery("#pmax").val() +
"&psize=" +
psize;
}
}
function toPrev() {
if (pindex <= 1) {
alert("已在首页!");
location.href = location.href;
} else {
location.href =
"blog_lists.html?pindex=" +
(parseInt(pindex) - 1) +
"&psize=" +
psize;
}
}
function toNext() {
if (pindex >= jQuery("#pmax").val()) {
alert("已在末页!");
location.href = location.href;
} else {
location.href =
"blog_lists.html?pindex=" +
(parseInt(pindex) + 1) +
"&psize=" +
psize;
}
}
script>
翻页器是纯前端的,交给后端处理一些逻辑开销大体验感差~
通过一个隐藏输入框存储最大页码,保证翻页器不发请求也能获取,并且每次页面刷新,这个值也会发生改变(极端情况下,有偏差是正常的,无关紧要,不是什么大事)
之前没有给登录页和注册页判断是否已登录,其实正常情况下是肯定未登录的,但是我们通过地方访问是能在登录状态下访问到的!
前端登录页:
function init() { jQuery.ajax({ method: "get", url: "/user/is_login", success: function (body) { if (body.code == 200 && body.data == true) { jQuery("#icon").attr("href", "img/logo1.png"); jQuery(".navigation img").attr("src", " img/logo1.png"); jQuery(".title").text("我的博客系统"); var newA = ""; newA += '我的博客'; newA += '写博客'; newA += '退出登录'; jQuery(".navigation").append(jQuery(newA)); } }, }); } init();
前端注册页:
function init() { jQuery.ajax({ method: "get", url: "/user/is_login", success: function (body) { if (body.code == 200 && body.data == true) { jQuery("#icon").attr("href", "img/logo1.png"); jQuery(".navigation img").attr("src", " img/logo1.png"); jQuery(".title").text("我的博客系统"); var newA = '主页'; newA += '我的博客'; newA += '写博客'; newA += '退出登录'; jQuery(".navigation").append(jQuery(newA)); } }, }); } init();
后端/user/is_login接口:
@RequestMapping("/is_login") public CommonResult isLogin(HttpServletRequest request) { boolean login = SessionUtils.getUser(request) != null; return CommonResult.success(login); }
后端拦截器配置:
.excludePathPatterns("/user/is_login")
效果:
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭!代码(持续更新):myblog_system/src · 游离态/马拉圈2023年9月 - 码云 - 开源中国 (gitee.com)