【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用

这篇具有很好参考价值的文章主要介绍了【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

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

1. 增加博文

1.1 预期效果

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

用户在网页中编写标题和正文,点击提交,选择

  1. 输入摘要
  2. 取消,继续编写文章

提交成功后,选择

  1. 继续写文章
  2. 返回“我的博客列表页”

1.1 约定前后端交互接口

后端:

  1. /art/publish
  2. 将前端传递过来的数据保存到数据库
  3. 返回受影响行数

前端:

  1. /art/publish
  2. 标题,正文,摘要
  3. 当前登录用户sessionid

1.2 后端代码

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. controller层

由于经常需要对字符串进行检查,我封装了一个方法:

  • 为什么前端检验完了,后端还检验呢?
    • 千万别相信“前端”,因为这个“前端”,可能不是浏览器正常的流程,也可能是通过postman等方式发送的请求,这个就可以绕开前端代码的校验~
    • 不用担心,因为
public class APPUtils {
   /**
     * 字符串全部都有长度才返回true
     * @param strings
     * @return
     */
    public static boolean hasLength(String... strings) {
        for(String x : strings) {
            if(!StringUtils.hasLength(x)) {
                return false;
            }
        }
        return true;
    }
}

修改:

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

@RequestMapping("/publish")
public CommonResult publish(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {
    // 1. 获取当前用户详信息
    UserInfo userInfo = SessionUtils.getUser(request);
    articleInfo.setUid(userInfo.getId());
    articleInfo.setPhoto(userInfo.getPhoto());
    // 2. 校验参数
    if(!APPUtils.hasLength(articleInfo.getContent(), articleInfo.getSummary(), articleInfo.getTitle())) {
        return CommonResult.fail(-1, "非法参数!");
    }
    // 3. 提交到数据库中
    int rows = articleService.publish(articleInfo);
    // 4. 返回
    return CommonResult.success(rows);
}
  1. service层
@Autowired
private ArticleMapper articleMapper;

public int publish(ArticleInfo articleInfo) {
    return articleMapper.insert(articleInfo);    
}
  1. mapper层
@Insert("insert into articleinfo (title, content, summary, uid, photo) values (#{title}, #{content}, #{summary}, #{uid}, #{photo})")
int insert(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除此接口

1.3 前端代码

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

function publish() {
    var title = jQuery("#text");
    var content = jQuery("#content");
    // 1. 参数校验
    if (title.val().trim() == "") {
        alert("标题不能为空!");
        title.focus();
        return false;
    }
    if (content.val().trim() == "") {
        alert("正文不能为空!");
        content.focus();
        return false;
    }
    // 2. 输入摘要
    var summary = prompt("请输入摘要:");
    if(summary == "") {
        return false;
    }
    // 3. 发送请求
    jQuery.ajax({
        url: "/art/publish",
        method: "POST",
        contentType: "application/json; charset=utf8",
        data: JSON.stringify({
            title: title.val().trim(),
            content: content.val().trim(),
            summary: summary.val().trim(),
        }),
        // 3. 处理响应
        success: function (body) {
            if (body.code == 200 && body.data == 1) {
                if(confirm("发布成功!请问是否继续创作?")) {
                    location.href = location.href;
                }else {
                    location.href = "myblog_lists.html";
                }
            } else {
                alert("发布失败:" + body.msg);
            }
        },
    });
}

1.4 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

为了避免写文章过程中session过去,我将session设置为永不过期:

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

2. 我的博客列表页

2.1 期待效果

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. 左侧窗口显示用户信息
  2. 右侧窗口显示用户创作的博文简介
    1. 标题
    2. 时间以及阅读量
    3. 摘要
    4. 查看正文,修改文章,删除文章按钮
  3. 右上角
    1. 点击主页跳转到所有人的博客列表页
    2. 点击写博客跳转到博客创作页
    3. 点击退出登录,后端删除登录记录,跳转到登录页面

2.2 显示用户信息以及博客信息

2.2.1 约定前后端交互接口

后端:

  1. /article/get_mylist
  2. 通过当前登录用户查询博客
  3. 返回用户信息以及博客信息的组合

前端:

  1. /article/get_mylist
  2. get
  3. 接受响应,投喂给页面
2.2.2 后端代码
  1. controller层
@RequestMapping("/get_mylist")
public CommonResult getMylist(HttpServletRequest request) {
    // 1. 获取当前登录用户
    UserInfo userInfo = SessionUtils.getUser(request);
    // 2. 通过此用户发布的所有文章
    List<ArticleInfo> list = articleService.getListByUid(userInfo.getId());
    // 3. 标题 / 正文太长 处理
    ArticleUtils.substringList(list);
    // 4. 返回给前端
    Map<String, Object> map = new HashMap<>();
    map.put("user", userInfo);
    map.put("list", list);
    return CommonResult.success(map);
}
// 文章工具类
public class ArticleUtils {

    //标题截取长度
    private static final int _TITLE_LENGTH = 40;
    //摘要截取长度
    private static final int _SUMMARY_LENGTH = 160;

    public static void substringList(List<ArticleInfo> list) {
        if(list != null && list.size() != 0) {
            // 并发处理 list 集合
            list.stream().parallel().forEach((art) -> {
                //标题截取
                if(art.getTitle().length() > _TITLE_LENGTH) {
                    art.setTitle(art.getTitle().substring(0, _TITLE_LENGTH) + "...");
                }
                //摘要截取
                if(art.getSummary().length() > _SUMMARY_LENGTH) {
                    art.setSummary(art.getSummary().substring(0, _SUMMARY_LENGTH) + "...");
                }
            });
        }
    }
}
  1. service层
public List<ArticleInfo> getListByUid(int uid) {
    return articleMapper.getListByUid(uid);
}
  1. mapper层
@Select("select * from articleinfo where uid = #{uid} order by id desc")
List<ArticleInfo> getListByUid(@Param("uid") int uid); //越晚发布排在越前
  1. 拦截器配置
    • 不排除此接口
  2. 时间格式配置

可以接受数据库时间的类型一般是:

  1. Date
  2. LocalDataTime
  3. TimeStamp

网络资料

LocalDateTime和Date是Java中表示日期和时间的两种不同的类,它们有一些区别和特点。

  1. 类型:LocalDateTime是Java 8引入的新类型,属于Java 8日期时间API(java.time包)。而Date是旧版Java日期时间API(java.util包)中的类。

  2. 不可变性:LocalDateTime是不可变的类型,一旦创建后,其值是不可变的。而Date是可变的类型,可以通过方法修改其值。

  3. 线程安全性:LocalDateTime是线程安全的,多个线程可以同时访问和操作不同的LocalDateTime实例。而Date是非线程安全的,如果多个线程同时访问和修改同一个Date实例,可能会导致不可预期的结果。

  4. 时间精度:LocalDateTime提供了纳秒级别的时间精度,可以表示更加精确的时间。而Date只能表示毫秒级别的时间精度。

  5. 时区处理:LocalDateTime默认不包含时区信息,表示的是本地日期和时间。而Date则包含时区信息,它的实际值会受到系统默认时区的影响。

而TimeStamp就是long类型的时间戳的包装~

对于时间格式的控制:

  1. json的构造本身是通过getter去获取的,所以可以重写getter来控制显示效果

  2. 全局配置:

    【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

    但是这只适合jdk8之前的Date类型

  3. 局部配置:

    • 对于时间类型的属性,是可以通过注解@JsonFormat来配置的:

    【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

2.2.3 前端代码

左:

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

右:

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

jQuery.ajax({
    type: "get",
    url: "/art/get_mylist",
    success: function (body) {
        if (body.code == 200) {
            // 1. 改变左侧窗口
            jQuery(".card img").attr("src", body.data.user.photo);
            jQuery(".card h3").text(body.data.user.name);
            if(body.data.user.git.trim() != "") {
                jQuery(".card a").attr("href", body.data.user.git);
            }
            jQuery("#count").text(body.data.list.length);
            // 2. 显示文章,构造博客html元素
            for (var blog of body.data.list) {
                console.log(body.title);
                var art =
                    '<div class="blog"><div class="title">' + blog.title + "</div>";
                art +=
                    '<div class="date">' +
                    blog.createtime +
                    " 阅读量:" +
                    blog.rcount +
                    "</div>";
                art += '<div class="content">' + blog.summary + "</div>";
                art += '<div class="thing">';
                art +=
                    '<a href="blog_detail.html?aid=' + blog.id + '">查看正文</a>';
                art +=
                    '<a href="myblog_update.html?aid=' + blog.id + '">修改文章</a>';
                art +=
                    '<div id="del" style="background-color: rgba(255, 0, 0, 0.6)" οnclick="del(' +
                    blog.id +
                    ')">删除文章</div>';
                art += "</div></div>";
                // 3. 追加到div.article
                jQuery(".article").append(jQuery(art));
            }
        }
    },
});

你也可以,以标签为单位去设置属性以及嵌套,这有逻辑的构建;而我这里是单纯的拼接字符串,用jQuery(str),构造html元素

2.2.4 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

2.3 删除文章

2.3.1 约定前后端交互接口

后端:

  1. /art/delete
  2. 根据当前登录用户id,和删除文章对应的作者id,判断是否有权限删除,有才能删除
  3. 返回受影响行数

前端:

  1. /art/delete
  2. post
  3. JSON:id(文章id)
  4. 如果受影响行数为1,刷新页面
2.3.2 后端代码
  1. controller层
@RequestMapping("/delete")
public CommonResult delete(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {
    // 1. 获取当前登录用户的id
    int uid = SessionUtils.getUser(request).getId();
    // 2. 设置到文章对象里
    articleInfo.setUid(uid);
    // 3. 删除
    int rows = articleService.delete(articleInfo);
    // 4. 返回
    return CommonResult.success(rows);
}
  1. service层
public int delete(ArticleInfo articleInfo) {
    return articleMapper.delete(articleInfo);
}
  1. mapper层
@Delete("delete from articleinfo where id = #{id} and uid = #{uid}")
// 查找文章和检测权限在一步搞定
int delete(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除
2.3.3 前端代码
function del(aid) {
    // 0. 参数校验
    if (parseInt(aid) == NaN || aid <= 0) {
        return false;
    }
    jQuery.ajax({
        method: "post",
        url: "/art/delete",
        contentType: "application/json; charset=utf8",
        data: JSON.stringify({
            id: aid,
        }),
        success: function (body) {
            if (body.code == 200 && body.data == 1) {
                location.href = location.href;
            } else {
                alert("删除失败!\n");
            }
        },
    });
}
2.3.4 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

2.4 退出登录

2.4.1 约定前后端交互接口

后端:

  1. /user/logout
  2. 根据当前用户进行删session操作
  3. 无返回值

前端:

  1. /user/logout
  2. a标签的get
2.4.2 后端代码
  1. controller层
@RequestMapping("/logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 设置为null也可以,但这是因为我们的判断原理的原因
    //SessionUtils.setUser(request, null);
    // 调用工具类里的注销方法
    SessionUtils.remove(request);
    response.sendRedirect("blog_login.html");
}
/**
 * 注销
 * @param request
 */
public static void remove(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if(session != null && session.getAttribute(ApplicationVariable.SESSION_KEY) != null) {
        session.removeAttribute(ApplicationVariable.SESSION_KEY);
    }
}
  1. 拦截器配置
    • 拦截,不排除
2.4.3 前端代码
<a href="/user/logout">退出登录</a>
2.4.4 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

3. 修改文章

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程
【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

预期效果就是:原有数据显示出来,供用户修改

3.1 页面初始化

3.1.1 约定前后端接口

后端:

  1. /art/get_art
  2. 根据uid和aid查询文章
  3. 返回文章信息

前端:

  1. /art/get_art
  2. post,json,aid
  3. 将数据投喂到网页
3.1.2 后端代码
  1. controller层
@RequestMapping("/get_art")
public CommonResult getArt(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {
    // 1. 获取当前登录用户的id
    int uid = SessionUtils.getUser(request).getId();
    // 2. 设置到文章对象里
    articleInfo.setUid(uid);
    // 3. 查询文章
    ArticleInfo art = articleService.getArt(articleInfo);
    // 4. 返回(查询不到一个对象,是null;如果查询不到对象集合,返回的是空集合)
    return art == null ? CommonResult.fail(-1, "查询不到!") : CommonResult.success(art);
}
  1. service层
public ArticleInfo getArt(ArticleInfo articleInfo) {
    return articleMapper.getArticleCheck(articleInfo);
}
  1. mapper层
@Select("select * from articleinfo where id = #{id} and uid = #{uid}")
ArticleInfo getArticleCheck(ArticleInfo articleInfo);//检查权限的查询文章

@Select("select * from articleinfo where id = #{id}")
ArticleInfo getArticle(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除
3.1.3 前端代码
<script>
    var aid = getParamValue("aid");
    // 1. 校验参数
    function init() {
        if (aid == null || aid <= 0) {
            alert("非法参数!");
            location.href = "myblog_lists.html";
            return false;
        }
        // 2. 查询文章
        jQuery.ajax({
            url: "/art/get_art",
            method: "post",
            contentType: "application/json; charset=utf8",
            data: JSON.stringify({
                id: aid,
            }),
            success: function (body) {
                if (body.code == 302) {
                    location.href = body.msg;
                    return false;
                }
                if (body.code == 200) {
                    jQuery("#text").val(body.data.title);
                    jQuery("#content").val(body.data.content);
                    jQuery("#summary").val(body.data.summary);//用隐藏输入框保存摘要信息
                } else {
                    alert("发布失败:" + body.msg);
                }
            },
        });
    }
    init();
</script>

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

注意:

  1. 如果直接写代码的话,而不是调用方法,默认页面跟代码一起加载,而调用方法是页面加载后调用此init方法
    • 如果不采取这种方式的话,会导致请求返回的页面,被拦截器拦下
  2. 为什么还是用json而不是用querystring直接发送请求
    • 习惯吧,因为json比较通用,如果还需要其他信息,querystring不方便
  3. 修改页跟添加页是一样的,为什么不重用?
    • 重用会导致一些没有必要的判断,不符合单一设计原则,麻烦/乱/开发不舒适,耦合度高…
3.1.4 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

3.2 修改文章

3.2.1 约定前后端交互接口

后端:

  1. /art/update
  2. 接受文章数据
  3. 返回受影响行数

前端:

  1. /art/update
  2. post,json,上传文章数据
  3. 成功则跳转到我的博客列表页
3.2.2 后端代码
  1. controller层
@RequestMapping("/update")
public CommonResult update(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) {
    // 0. 确认用户
    int uid = SessionUtils.getUser(request).getId();
    articleInfo.setUid(uid);
    // 1. 校验参数
    if(!APPUtils.hasLength(articleInfo.getContent(), articleInfo.getSummary(), articleInfo.getTitle())) {
        return CommonResult.fail(-1, "非法参数!");
    }
    // 2. 修改
    int rows = articleService.update(articleInfo);
    // 3. 返回
    return CommonResult.success(rows);
}
  1. service层
public int update(ArticleInfo articleInfo) {
    return articleMapper.updateArticle(articleInfo);
}
  1. mapper层
    • 必须是有权限才能修改
    • 更新时间修改为当下
@Update("update articleinfo set content = #{content}, title = #{title}, summary = #{summary}, updatetime = now() where id = #{id} and uid = #{uid}")
int updateArticle(ArticleInfo articleInfo);
  1. 拦截器配置
    • 拦截,不排除
3.2.3 前端代码

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

function update() {
    if (aid == null || aid <= 0) {
        alert("非法参数!");
        location.href = "myblog_lists.html";
        return false;
    }
    var title = jQuery("#text");
    var content = jQuery("#content");
    // 1. 参数校验
    if (title.val().trim() == "") {
        alert("标题不能为空!");
        title.focus();
        return false;
    }
    if (content.val().trim() == "") {
        alert("正文不能为空!");
        content.focus();
        return false;
    }
    // 2. 输入摘要
    var summary = prompt("请输入摘要:", jQuery("#summary").val());
    if (summary.trim() == "") {
        return false;
    }
    jQuery("#summary").val(summary);
    // 3. 发送请求
    jQuery.ajax({
        url: "/art/update",
        method: "POST",
        contentType: "application/json; charset=utf8",
        data: JSON.stringify({
            id: aid,
            title: title.val().trim(),
            content: content.val().trim(),
            summary: summary.trim(),
        }),
        // 3. 处理响应
        success: function (body) {
            if (body.code == 302) {
                location.href = body.msg;
                return false;
            }
            if (body.code == 200 && body.data == 1) {
                location.href = "myblog_lists.html";
            } else {
                alert("修改失败:" + body.msg);
            }
        },
    });
}
3.2.4 测试

4. 博客详情页

4.1 期待效果

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. 根据是否登录,改变导航栏
  2. 根据querystring中的aid,显示对应的博文,和作者信息
  3. 每次访问成功,阅读量加1(本次显示是加1之前)
  4. 作者的文章总数通过后端计算
  5. 正文以html的样式渲染出来

这样的复杂查询可以用到并发编程:

  • 【JavaEE】Callable接口(NO.6线程创建方法)-JUC的常见类-与线程安全有关集合类_s:103的博客-CSDN博客
  • 用有返回值的线程创建方式(获取的时候若未结束,等待…)

4.2 约定前后端交换接口

后端:

  1. /art/detail
  2. 通过aid,找到文章
  3. 通过文章,uid找到作者,查询总文章数,通过aid修改文章阅读量
  4. 返回:
    1. “login”,true/false,true代表登录中
    2. “count”,文章数
    3. “user”,用户
    4. “art”,文章

前端:

  1. /art/detail
  2. json,aid
  3. 接受响应,投喂给代码

4.3 后端代码

  1. controller层
    1. 查询文章信息
    2. 校验文章是否存在
    3. 根据uid查询用户总文章数的任务
    4. 根据uid查询用户信息的任务
    5. 根据aid更新阅读量的任务
    6. 线程池执行任务
    7. 构造响应数据,并返回
@Autowired
private ArticleService articleService;
@Autowired
private UserService userService;
@RequestMapping("/detail")
public CommonResult detail(@RequestBody ArticleInfo articleInfo, HttpServletRequest request) throws ExecutionException, InterruptedException {
    // 1. 查询文章信息
    ArticleInfo art = articleService.getArtByAid(articleInfo);
    // 2. 校验文章是否存在
    if(art == null) {
        return CommonResult.fail(-1, "非法参数!");
    }
    // 3. 根据uid查询用户总文章数的任务
    FutureTask<Integer> task1 = new FutureTask<Integer>(() -> {
        return articleService.getArtNumberByUid(art.getUid());
    });
    // 4. 根据uid查询用户信息的任务
    FutureTask<UserInfo> task2 = new FutureTask<UserInfo>(() -> {
        return userService.getUserByUid(art.getUid());
    });
    // 5. 根据aid更新阅读量的任务
    FutureTask<Integer> task3 = new FutureTask<Integer>(() -> {
        return articleService.incrementRCount(art.getId());
    });
    // 6. 线程池执行任务
    APPUtils.THREAD_POOL.submit(task1);
    APPUtils.THREAD_POOL.submit(task2);
    APPUtils.THREAD_POOL.submit(task3);
    // 7. 构造响应数据,并返回
    Map<String, Object> map = new HashMap<>();
    map.put("login", SessionUtils.getUser(request) != null);
    map.put("count", task1.get());
    map.put("user", task2.get());
    map.put("art", art);
    return CommonResult.success(map);
}

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. service层

ArticleService:

public int getArtNumberByUid(int uid) {
    return articleMapper.getArtNumberByUid(uid);
}

public int incrementRCount(int aid) {
    return articleMapper.incrementRCount(aid);
}

UserService:

public UserInfo getUserByUid(int uid) {
    return userMapper.getUserByUid(uid);
}
  1. mapper层

ArticleMapper:

@Select("select count(*) from articleinfo where uid=#{uid}")
int getArtNumberByUid(@Param("uid") int uid);

@Update("update articleinfo set rcount = rcount + 1 where id = #{aid}")
int incrementRCount(@Param("aid") int aid);

UserMapper:

@Select("select * from userinfo where id = #{uid}")
UserInfo getUserByUid(@Param("uid") int uid);
  1. 拦截器配置
    • 排除拦截
    • editor.md是个目录,要排除整个目录才对,不然后面渲染不上去,之前可以渲染是因为我们处于登录状态~
    • 因为详情页不需要登录~

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

4.4 前端代码

  1. 导航栏

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  • 网页图标

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. 右侧用户卡片

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

  1. 右侧文章信息

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程

var aid = getParamValue("aid");
function init() {
    if (aid == null || aid <= 0) {
        alert("非法参数!");
        return false;
    }
    jQuery.ajax({
        method: "post",
        url: "/art/detail",
        contentType: "application/json; charset=utf8",
        data: JSON.stringify({
            id: aid,
        }),
        success: function (body) {
            if (body.code == 200) {
                // 1. 导航栏显示
                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("#add").hide();
                    jQuery("#logout").text("登录");
                    jQuery("#logout").attr("href", "blog_login.html");
                }
                // 2. 文章数显示
                jQuery("#count").text(body.data.count);
                // 3. 用户信息显示
                jQuery(".card img").attr("src", body.data.user.photo);
                jQuery(".card h3").text(body.data.user.name);
                if (body.data.user.git.trim() != "") {
                    jQuery(".card a").attr("href", body.data.user.git);
                }
                // 4. 文章信息显示
                jQuery(".article h3").text(body.data.art.title);
                jQuery(".article .date").text(
                    body.data.art.createtime + " 阅读量:" + body.data.art.rcount
                );
                editormd.markdownToHTML("pc", {
                    markdown: body.data.art.content,
                });
            } else {
                alert("查看失败:" + body.msg);
            }
        },
    });
}
init();

4.5 测试

【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用,JavaEE,状态模式,java-ee,spring,网络,多线程


文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

代码:myblog_system/src · 游离态/马拉圈2023年9月 - 码云 - 开源中国 (gitee.com)文章来源地址https://www.toymoban.com/news/detail-695871.html


到了这里,关于【个人博客系统网站】我的博客列表页 · 增删改我的博文 · 退出登录 · 博客详情页 · 多线程应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 什么?博客园主题比我的个人博客好看??

    最近逛博客园,发现我的园子还挺好看,但是还不够好看,所以通过我百度发现SimpleMemory主题还可以继续添加新的东西,当然这些东西不一定非得用SimpleMemory主题才行,但是搭配SimpleMemory主题是真的好看呀(比我的博客好看多了)。 访问不进去GitHub,又不想花钱使用魔法,看

    2024年02月16日
    浏览(26)
  • 长短期神经网络LSTM的博文分类,长短期神经网络的原理分析

    目录 背影 摘要 代码和数据下载:长短期神经网络LSTM的博文分类,长短期神经网络微博博文分类(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88498278 LSTM的基本定义 LSTM实现的步骤 长短期神经网络LSTM的博文分类,长短期神经网络微博博文分类 结果

    2024年02月05日
    浏览(35)
  • 大学生PHP个人博客网站源码 简单个人动态网站设计模板 PHP毕业设计成品 学生PHP MYSQL日志管理系统网页

    PHP MYSQL个人博客网站作品使用php+mysql开发,系统编码简单,大学生PHP毕业设计水平。系统随处可见增删改查等基本操作,有批量删除之功能,涉及的知识点比较全面。 数据库共6张数据表,表之间有关联,设计合理;系统具有管理员和会员两种用户角色,管理员(即日志的所

    2024年02月12日
    浏览(53)
  • bye 我的博客网站

    Bye🙋🙋🙋,我的博客网站。在我的服务器上运行了9个月之久的博客网站要和大家Bye了。 背景 可能很多人不知道我的这个博客网站的存在,好吧,最后一次展示它了,博客网站地址在这里,它是基于开源的一款Java开发的CMS博客建站平台:PerfreeBlog构建的。官方的网站首页是

    2024年02月13日
    浏览(40)
  • wordpress我的个人网站搭建

    WordPress是一个功能强大且易于使用的网站管理平台。它是基于PHP和MySQL构建的,可以在各种不同的主机上运行。 需求 最低版本要求 PHP 7.4 或更高版本 MySQL 5.6 或更高版本 Web服务器 任意(如:Apache、Nginx) 存储空间 足够存储数据的空间 带宽 足够的数据传输带宽 内存 至少51

    2024年02月15日
    浏览(35)
  • 基于Hugo 搭建个人博客网站

    目录 1.环境搭建 2.生成博客 3.设置主题 4.将博客部署到github上 1)安装Homebrew brew是一个在 macOS 操作系统上用于管理软件包的包管理器。类似于centos下的yum或者ubuntu下的apt,它允许用户通过命令行安装、更新和管理各种软件工具、库和应用程序。 前往hb官网,复制下载命令,打

    2024年02月09日
    浏览(33)
  • 我的个人网站——宏夏Coding上线啦

    网站地址:宏夏Coding Github地址:🔥🔥宏夏coding网站,致力于为编程学习者、互联网求职者提供最需要的内容!网站内容包括求职秘籍,葵花宝典(学习笔记),资源推荐等内容。 大家好,我是宏夏c,目前是一名软件工程专业的大三学生。🙂 回顾起大一入学的那个初夏,我

    2024年02月09日
    浏览(29)
  • hexo + github 创建个人博客网站

    nodejs 和 npm git hexo 是一个静态博客生成网站,可以快速制作自己的博客网站并部署 安装hexo npm install hexo-cli -g 创建项目 hexo init 本地预览 hexo s 新建仓库 创建一个名为[用户名].github.io的仓库 下载自动部署插件 npm install hexo-deployer-git --save 修改hexo的配置文件 _config.yml 在deplay中添

    2024年02月05日
    浏览(50)
  • 10分钟搭建一个免费个人博客网站

    准备工作 有Gitee账号 有安装git 会 markdown 编写文档 Node.js 版本 = 8.6 博客采用VuePress搭建,Gitee部署,接下来,5步搞定。 1.创建项目 创建项目目录,并初始化项目,安装VuePress 2. 创建目录结构 3.完成基础配置 配置主题,定义自己的导航栏 配置首页 在 myblog/package.json 中添加一些

    2024年02月09日
    浏览(35)
  • 我的个人网站 —— 直接使用GPT4

    前期回顾     打造极简风格动效 —— 5 分钟轻松实现惊艳、震撼人心的视觉效果_彩色之外的博客-CSDN博客 css Loading 实战教学 https://blog.csdn.net/m0_57904695/article/details/131156011?spm=1001.2014.3001.5501 ​ 目录  ✈  线上预览: ✅  G4 WEB 效果图例 :   📢 拷贝运行试试  🔱 手机版:

    2024年02月09日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包