“文章定时发布功能”如何实现?(代码+详细注释)
  TEZNKK3IfmPf 2024年03月30日 17 0

设计思路


分析

“文章定时发布功能”如何实现?(代码+详细注释)

当用户选择好定时发布时间以后,点击定时发布按钮之后,向后端发起 ajax 请求,请求中的数据有:“文章标题、文章正文内容、定时发布时间”,后端接收到数据以后,首先对客户端传入数据进行非空校验,然后起一个线程,实现一个类似自旋锁的操作:“每过 2s 就进行一次自旋询问操作”,通俗来讲就是每过 2s 询问一下当前时间是否大于定时发布时间,若大于,就将文章发布,若不大于就使用 wait(2000) 让线程等待 2s 。 

这样就可以实现文章定时发布功能喽~

前后端交互接口

请求

POST /art/timeadd
Content-Type: application/json
{
    "title": jQuery('#title').val(), //获取标题
    "content": editor.getValue(),    //获取正文
    "postTime": postTime.val()       //获取定时发布时间
}

响应

Ps:采用同一返回数据格式处理(“code:状态码,msg:信息,data:数据”)

HTTP1.1 200 OK
Content-Type: application/json
{
    code: 200, //状态码
    msg: "",   //信息
    data: 1    //数据
}

代码实现和详细注释


数据库设计

文章表设计如下:

create table articleinfo(
    id int primary key auto_increment,
    title varchar(100) not null,
    content text not null,
    createtime timestamp default current_timestamp,
    updatetime timestamp default '1970-01-01 10:00:00',
    uid int not null,
    rcount int not null default 1,
    `state` int default 1,
)

前后端交互

客户端开发

创建 input 控件,type 类型为 datetime-local (可以选择年、月、日、时、分)

Ps:这里要注意 datetime-local 的格式为:"yyyy-mm-ddThh:mm"

创建 button 控件,点击触发 js 代码。

<input type="datetime-local" id="pubdate">
<button onclick="myTimeSub()" id="pubdate-button">定时发布</button>

js 代码实现如下:

        //定时发布
        function myTimeSub() {
            var postTime = jQuery("#pubdate");
            //非空校验
            if (postTime.val() == "") {
                alert("请选择定时发布时间!");
                return;
            }
            if(confirm("是否确认发布!")) {
                jQuery.ajax({
                    type: "POST",
                    url: "/art/timeadd",
                    data: {
                        "title": jQuery('#title').val(),
                        "content": editor.getValue(),
                        "postTime": postTime.val()
                    },
                    success: function (result) {
                        if (result != null && result.code == 200 && result.data == 1) {
                            alert("定时发布成功!");                       
                            location.assign("/myblog_list.html");
                        } else {
                            alert("定时发布失败,请稍后重试");
                        }
                    }
                });
            }
        }

服务器开发

按照刚刚讲到的分析思路和前后端交互接口不难实现~

Ps:定时发布时间的格式为:"yyyy-mm-ddThh:mm"

Controller 层代码如下;

    @RequestMapping("/timeadd")
    public AjaxResult timeAdd(HttpServletRequest request, ArticleInfoVO articleInfoVO) {
        //非空校验
        if(articleInfoVO == null || !StringUtils.hasLength(articleInfoVO.getTitle()) ||
        !StringUtils.hasLength(articleInfoVO.getContent())) {
            return AjaxResult.fail(403, "参数错误!");
        }
        UserInfo userInfo = UserSessionUtils.getUser(request);
        if(userInfo == null || !StringUtils.hasLength(userInfo.getUsername()) ||
        !StringUtils.hasLength(userInfo.getPassword())) {
            return AjaxResult.fail(403, "参数错误");
        }
        //设置定时发布,启动一个线程,每两秒询问一次是否到达过期时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Thread queryTime = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    while(true) {
                        if(ArticleInfoUtils.checkOvertime(sdf.format(System.currentTimeMillis()),
                        articleInfoVO.getPostTime())) {
                            //到达过期时间
                            ArticleInfo articleInfo = new ArticleInfo();
                            articleInfo.setTitle(articleInfoVO.getTitle());
                            articleInfo.setContent(articleInfoVO.getContent());
                            articleInfo.setUid(userInfo.getId());
                            //添加文章
                            articleService.add(articleInfo);
                            break;
                        }
                        try {
                            System.out.println("休眠2s");
                            lock.wait(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        queryTime.start();
        //发布博客
        return AjaxResult.success(1);
    }

定时发布时间检测:

    /**
     * 定时发布
     * 用来检验是否超时
     * @param startTime 起始时间(yyyy-MM-dd HH:mm)
     * @param endTime 定时发布时间(yyyy-mm-ddThh:mm)
     * @return
     */
    public static boolean checkOvertime(String startTime, String endTime) {
        String[] st = startTime.split(" ");
        String[] et = endTime.split("T");
        //yyyy-mm-dd
        String[] symd = st[0].split("-");
        String[] eymd = et[0].split("-");
        //hh:mm
        String[] shm = st[1].split(":");
        String[] ehm = et[1].split(":");
        //进行时间比较(一次按年月日进行比较,只要大于定时发布时间就返回 true,反之返回 false)
        if(Integer.parseInt(symd[0]) > Integer.parseInt(eymd[0])) return true;
        else if(Integer.parseInt(symd[0]) < Integer.parseInt(eymd[0])) return false;
        if(Integer.parseInt(symd[1]) > Integer.parseInt(eymd[1])) return true;
        else if(Integer.parseInt(symd[1]) < Integer.parseInt(eymd[1])) return false;
        if(Integer.parseInt(symd[2]) > Integer.parseInt(eymd[2])) return true;
        else if(Integer.parseInt(symd[2]) < Integer.parseInt(eymd[2])) return false;
        if(Integer.parseInt(shm[0]) > Integer.parseInt(ehm[0])) return true;
        else if(Integer.parseInt(shm[0]) < Integer.parseInt(ehm[0]))return false;
        if(Integer.parseInt(shm[1]) >= Integer.parseInt(ehm[1])) return true;
        else return false;
    }
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月30日 0

暂无评论

推荐阅读
TEZNKK3IfmPf