【个人博客系统网站】 所有人的博客列表页 · 分页功能实现

【JavaEE】进阶 · 个人博客系统(5)

文章目录

  • 【JavaEE】进阶 · 个人博客系统(5)
    • 1. 预期效果
    • 2. 约定前后端交互接口
    • 3. 分页原理
    • 4. 后端代码
    • 5. 前端代码
    • 6. 测试
    • 7. 补充

【JavaEE】进阶 · 个人博客系统(5)

1. 预期效果

  1. 分页
  2. 登录状态下和非登录状态下的导航栏不一样
  3. 查看正文,也就是详情页
  4. 通过下面的四个按钮进行翻页
    1. 首页点击首页,和上一页会弹窗提示
    2. 末页点击末页,和下一页会弹窗提示

2. 约定前后端交互接口

后端:

  1. /art/all_list
  2. 识别参数,pindex(页码)和 psize(页内最大博客数)
  3. 通过这两个数,判断截取表的哪一部分(limit x offset y)
  4. 返回数据组合
    1. login,是否登录
    2. pMax,最大页码
    3. list,几个博客信息

前端:

  1. /art/all_list
  2. 通过手段发送querystring的方式传递pindex(页码)和 psize(页内最大博客数)和给后端

3. 分页原理

后端只要知道页码和一页多少条数据,就可以计算出要选取哪几条数据(发送期间博客表发生改变而有偏差,这无所谓,很正常,无关紧要的事)

psize => 一页的限制,就是limit 后面的值

pindex 页前有多少条数据,就是偏移量 => psize × (pindex - 1) => 页就是 offset 后面的值

所有博客数 / psize,向上取整就是最大页码pMax,如果所有博客数为0,则前端应该显示 当前在第0页,共0页

pindex的正确性,正常情况下是不会错误的,因为前端知道最大页码pMax,则不会继续翻下一页~

  • 而通过自己手写querystring,导致页码太大的情况也有,我们后端只需要处理pMax < pindex的异常情况就行了~
  • psize过大则无所谓,大不了一整页显示所有的数据

4. 后端代码

  1. controller层
@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);
}
  1. service层
public List<ArticleInfo> getSubList(int limit, int offset) {
    return articleMapper.getSubList(limit, offset);
}

public int getNumber() {
    return articleMapper.getNumber();
}
  1. mapper层
@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();
  1. 拦截器配置
    • 不拦截

.excludePathPatterns("/art/all_list")

5. 前端代码

  1. 导航栏

【个人博客系统网站】 所有人的博客列表页 · 分页功能实现_第1张图片

  1. 页面主体

【个人博客系统网站】 所有人的博客列表页 · 分页功能实现_第2张图片

  1. 翻页器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>
  1. 翻页器是纯前端的,交给后端处理一些逻辑开销大体验感差~

  2. 通过一个隐藏输入框存储最大页码,保证翻页器不发请求也能获取,并且每次页面刷新,这个值也会发生改变(极端情况下,有偏差是正常的,无关紧要,不是什么大事)

在这里插入图片描述

  1. 页码加操作的时候,可能触发字符串拼接,所以要手动转换一下~

【个人博客系统网站】 所有人的博客列表页 · 分页功能实现_第3张图片

6. 测试

  1. 是否登录:

  1. 翻页功能

  1. pindex过大,psize过大

  1. 数据库,表中无数据

7. 补充

之前没有给登录页和注册页判断是否已登录,其实正常情况下是肯定未登录的,但是我们通过地方访问是能在登录状态下访问到的!

前端登录页:

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)


你可能感兴趣的:(JavaEE,状态模式,java-ee,spring,网络,数据库,java,多线程)