自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

这篇具有很好参考价值的文章主要介绍了自己动手搭网站(六):javaweb搭建一个简单的个人博客系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

这篇博主会介绍下我用javaweb搭建的个人博客系统,源码也会打包放到gitee上,需要的朋友可以自取,大家互相学习,请不要直接CV。
tip:本篇承上篇,许多基本内容在上篇谈到,建议看之前先浏览下上篇博客。
上篇:自己动手搭网站(五):javaweb基础:登录功能

系列总目录:自己动手搭建网站系列总目录

gitee仓库链接

一、一点建网站的背景知识

在正式介绍代码前,博主先谈谈个人了解的一点web背景知识,也是博主接触web后“东拼西凑”来的,若有不当之处,希望大家指正。

最早的网站是非常简单的,基本就是用html和css写的一些静态页面,几乎没有什么交互能力,只是用来展示某些信息的。这个时期的web技术也常被称为web1.0

后来,随着技术的不断发展,C#、php、java等语言逐渐扩展到web领域,或者说,它们本来便是“应运而生”的。这些高级语言的加入使得网站渐渐有了交互能力,不再是只能看的页面了。也被称为web2.0时代,这个时期出现了许多经典的web建站技术栈,比如下面几个:
javaweb系列 (j2EE /javaweb,前端jsp,后端java执行各种复杂操作;最先由sun公司提出,后来sun公司被oracle收购,现在oracle的网站可能还是用j2ee这套,j2ee比较适合大型网站,但是原生的j2ee真的很复杂,现在发展简化到了“spring(boot)+前端”的模式,方便多了,也是目前比较主流的网站开发技术栈)、
asp.net系列(感觉是微软仿照jsp那套做得,前端asp,后端C#执行各种复杂操作,顺便一说,C#和Java据说有90%的相似度)、
php(这个博主没怎么用过,不过听说php可以嵌入html中,导致前后端的界限模糊消失,增加了中小型网站开发效率的同时也使得其很难用于大型网站的开发并且维护也变得更加困难,但目前似乎仍有不少网站用着这套技术栈)
当然,上述还称不上web技术栈,一般还要加上数据库(mysql)、操作系统(centos)、服务器(tomcat、Nginx等)…形成从开发到部署的一整套技术,便可称之为web技术栈了。

web技术博大精深,近年来web3.0的概念也逐渐产生,涉及更复杂的用户交互体验,甚至渗透到生活的方方面面,已经渐渐超脱网站的限制而走向更多元的发展方向。入坑的朋友们,有没有觉得“任重而道远”呢?

二、个人博客系统介绍

闲话少说,咱们步入正题,这次博主采用的技术栈为javaweb(jsp、servlet、jdbc、mysql、tomcat),jsp主要是写前端页面、servlet和jdbc后端操作和连接数据库、tomcat是web服务器、mysql就不必多说了,吾等开发者最青睐的开源数据库。关于jsp、servlet、jdbc大家有疑问的话可以看参考资料中狂神的相关视频,博主主要也是跟着这视频学的。这次用的集成开发环境是idea2022.1
关于用idea新建一个简单的web项目在我放到另外一篇博客
idea基本web开发环境配置及新建javaweb项目

1、核心功能和数据库

系统非常简单,核心功能就两个:登录和博客管理(发布、编辑、修改、展示)
数据库表我也就建了两个,一个user表,一个blog表,分别服务于上面两个功能。登录方面,就简单的登录,甚至没有注册和找回密码等功能,因为是个人博客系统,注册什么的没太大必要(绝对不是因为偷懒,确信!)


-- 创建数据库
create database if not exists blog_system; 
use blog_system;

-- 创建用户表
create table user(
    user_id     varchar(20) primary key,
    password    varchar(20)
);

-- 创建博客表,主键为blog_id,无符号int,自增
create table blog(
    blog_id     int     unsigned auto_increment primary key,
    author      varchar(20)  not null,
    title       varchar(40)  not null,
    content     text     not null,
    create_time datetime not null,
    update_time datetime not null,
    is_deleted   tinyint  unsigned not null
);

-- 向用户表中插入一条数据
insert into user(user_id,password) values('admin','test@123');

-- 向博客表中插入一条数据
insert into blog(author,title,content,create_time,update_time,is_deleted) values("微光落尘","###测试文章","嘻嘻哈哈","2022-08-31 20:36:08","2022-08-31 20:36:08",0);

2、前端页面

这次博主用的前端框架为bootstrap5,其实和bootstrap3也差不了多少,当初只是想了解下最新的bootstrap。涉及到博客功能,还引入了一个开源项目editor.md ,引入后webapp下的目录结构大概是这样子的
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
博主在jsp页面插入了一些js脚本,用来和后端交互数据,其中最重要的函数是$.ajax(),关于此方法的详细介绍,参见ajax()方法详解,简单来说就是个用来向后端传递数据并接收后端传回参数的函数。

因为最上面部分和左侧导航栏重复使用,我把它们抽出来做为母版页header.jsp和left.jsp,之后在jsp里面用<%@ include file=“header.jsp”%>引入进来就行。页面相比于第四篇中介绍的几个页面有了一些改变。下面是部分前端页面的代码:

header.jsp

<%--网站头部母版页--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<div style="margin-top:0px">
<div class="topImg">
    <h1>欢迎来小尘空间</h1>
    <p>小站虽小,或有其妙</p>
</div>
    <nav class="navbar navbar-expand-sm bg-white navbar-white border-bottom">
        <div class="container-fluid align-items-center">
            <div>
                <ul id="navBar" class="nav nav-pills">
                    <li id="mianPage" class="nav-item"><a href="index.jsp" class="nav-link active" aria-current="page">主页</a></li>
                    <li id="scenery" class="nav-item"><a href="scenery.jsp" class="nav-link">美景分享</a></li>
                    <li id="blog" class="nav-item"><a href="paging" class="nav-link">博客文章</a></li>
                    <li id="about" class="nav-item"><a href="about.jsp" class="nav-link">关于本站</a></li>
                </ul>
            </div>

            <div class="dropdown col-1 text-end">
                <a href="#" class="d-block link-dark text-decoration-none dropdown-toggle" id="dropdownUser1" data-bs-toggle="dropdown" aria-expanded="false">
                    <img src="img/north-star-2869817_1920.jpg" alt="mdo" width="40" height="40" class="rounded-circle">
                </a>
                <ul class="dropdown-menu text-small" aria-labelledby="dropdownUser1">
                    <li><a class="dropdown-item" href="personalCenter/personalCenter.jsp">个人中心</a></li>
                    <li><hr class="dropdown-divider"></li>
                    <li><a class="dropdown-item" href="publish.jsp">发布文章</a></li>
                    <li><hr class="dropdown-divider"></li>
                    <li><a class="dropdown-item" href="login.jsp">登录</a></li>
                    <li><hr class="dropdown-divider"></li>
                    <li><a class="dropdown-item" href="login.jsp">退出</a></li>
                </ul>
            </div>
        </div>
    </nav>
</div>
<script type="text/javascript">
    $(document).ready(function () {
        //console.log("changing active...")
        // each 是 为每一个匹配的元素 执行定义的方法
        $("#navBar").find("li").each(function (){
            var a = $(this).find("a:first")[0];
            // location.pathname 获取当前浏览器上的url路径部分
            if ( location.pathname.search($(a).attr("href")) !== -1) {
                $(a).addClass("active");
            } else {
                $(a).removeClass("active");
            }
        });
    });
</script>

left.jsp


<%--网站个人中心侧边栏--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<div style="width: 280px;height: 100vh;background-color: rgba(1,1,19,0.4);position: fixed">
    <a href="personalCenter.jsp" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none">
        <svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"/></svg>
        <span class="fs-4">个人中心</span>
    </a>
    <hr>
    <ul class="nav nav-pills flex-column mb-auto" id="leftNav">
        <li class="nav-item">
            <a href="personalCenter.jsp" class="nav-link text-white active" aria-current="page">
                <svg class="bi me-2" width="16" height="16"><use xlink:href="#home"/></svg>
                个人资料
            </a>
        </li>
        <li>
            <a href="blogManagement.jsp" class="nav-link text-white">
                <svg class="bi me-2" width="16" height="16"><use xlink:href="#speedometer2"/></svg>
                博客管理
            </a>
        </li>
        <li>
            <a href="../index.jsp" class="nav-link text-white">
                <svg class="bi me-2" width="16" height="16"><use xlink:href="#speedometer2"/></svg>
                返回主页
            </a>
        </li>
    </ul>
</div>
<script type="text/javascript">
    $(document).ready(function () {
        //console.log("changing active...")
        // each 是 为每一个匹配的元素 执行定义的方法
        $("#leftNav").find("li").each(function () {
            var a = $(this).find("a:first")[0];
            // location.pathname 获取当前浏览器上的url路径部分
            if ( location.pathname.search($(a).attr("href")) !== -1) {
                $(a).addClass("active");
            } else {
                $(a).removeClass("active");
            }
        });
    });
</script>

主页(index.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap5/css/bootstrap.min.css">
    <script src="bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <link href="css/myStyle.css"  rel="stylesheet">

</head>
<body>
<%@ include file="header.jsp"%>

<div class="container">
    <div class="row" style="height: 80vh">
            <!-- 轮播 -->
            <div id="demo" class="carousel slide" data-bs-ride="carousel" style="margin-top:5vh">

                <!-- 指示符 -->
                <div class="carousel-indicators">
                    <button type="button" data-bs-target="#demo" data-bs-slide-to="0" class="active"></button>
                    <button type="button" data-bs-target="#demo" data-bs-slide-to="1"></button>
                    <button type="button" data-bs-target="#demo" data-bs-slide-to="2"></button>
                </div>

                <!-- 轮播图片 -->
                <div class="carousel-inner">
                    <div class="carousel-item active">
                        <img src="http://static.runoob.com/images/mix/img_fjords_wide.jpg" class="d-block" style="width:100%">
                    </div>
                    <div class="carousel-item">
                        <img src="http://static.runoob.com/images/mix/img_nature_wide.jpg" class="d-block" style="width:100%">
                    </div>
                    <div class="carousel-item">
                        <img src="http://static.runoob.com/images/mix/img_mountains_wide.jpg" class="d-block" style="width:100%">
                    </div>
                </div>

                <!-- 左右切换按钮 -->
                <button class="carousel-control-prev" type="button" data-bs-target="#demo" data-bs-slide="prev">
                    <span class="carousel-control-prev-icon"></span>
                </button>
                <button class="carousel-control-next" type="button" data-bs-target="#demo" data-bs-slide="next">
                    <span class="carousel-control-next-icon"></span>
                </button>
            </div>
    </div>
</div>

<div class="text-center" style="margin-bottom:0;background-color: rgba(150,145,145,0.4)">
    <p style="color:#0000FF;font-size:30px"><a href="message.jsp">给我留言
        <span class="glyphicon glyphicon-pencil"></span>
    </a>
    </p>
    <br>
    <p>备案信息:暂无</p>
</div>
</body>
</html>


效果图如下
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
美景分享页(scenery.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap5/css/bootstrap.min.css">
    <script src="bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <link href="css/myStyle.css"  rel="stylesheet">
</head>
<body>
<div>
<div style="width:100vw;height:40px;position:fixed;left:0px;top:0px;z-index: 999;background-color: rgba(30,144,255,0.4)">
    <ul id="navBar" class="nav nav-pills">
        <li id="mianPage" class="nav-item"><a href="index.jsp" class="nav-link active" aria-current="page">主页</a></li>
        <li id="scenery" class="nav-item"><a href="scenery.jsp" class="nav-link">美景分享</a></li>
        <li id="blog" class="nav-item"><a href="paging" class="nav-link">博客文章</a></li>
        <li id="about" class="nav-item"><a href="about.jsp" class="nav-link">关于本站</a></li>
    </ul>
</div>
    <!-- 轮播 -->
    <div id="demo" class="carousel slide" data-bs-ride="carousel">

        <!-- 指示符 -->
        <div class="carousel-indicators">
            <button type="button" data-bs-target="#demo" data-bs-slide-to="0" class="active"></button>
            <button type="button" data-bs-target="#demo" data-bs-slide-to="1"></button>
            <button type="button" data-bs-target="#demo" data-bs-slide-to="2"></button>
        </div>

        <!-- 轮播图片 -->
        <div class="carousel-inner">
            <div class="carousel-item active">
                <img src="img/pic1.jpg" class="d-block" style="width:100%;height: 100vh">
            </div>
            <div class="carousel-item">
                <img src="img/pic2.jpg" class="d-block" style="width:100%;height: 100vh">
            </div>
            <div class="carousel-item">
                <img src="img/pic3.jpg" class="d-block" style="width:100%;height: 100vh">
            </div>
        </div>

        <!-- 左右切换按钮 -->
        <button class="carousel-control-prev" type="button" data-bs-target="#demo" data-bs-slide="prev">
            <span class="carousel-control-prev-icon"></span>
        </button>
        <button class="carousel-control-next" type="button" data-bs-target="#demo" data-bs-slide="next">
            <span class="carousel-control-next-icon"></span>
        </button>
    </div>
</div>
</body>
<script type="text/javascript">
//这个函数用来操作导航栏的蓝色激活胶囊,但是有个小bug...
    $(document).ready(function () {
        console.log("changing active...")
        // each 是 为每一个匹配的元素 执行定义的方法
        $("#navBar").find("li").each(function () {
            var a = $(this).find("a:first")[0];
            // location.pathname 获取当前浏览器上的url路径部分
            if ( location.pathname.search($(a).attr("href")) !== -1) {
                $(a).addClass("active");
            } else {
                $(a).removeClass("active");
            }
        });
    });
</script>
</html>

效果图如下:
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
博客列表展示页(blogListPage.jsp)
这里使用了jstl的一些标签来生成动态博客列表,并做了分页功能,分页功能的实现参见参考资料给的链接。

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap5/css/bootstrap.min.css">
    <script src="bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <link href="css/myStyle.css"  rel="stylesheet">
</head>
<body>
<%@ include file="header.jsp"%>
<div class="row">
<div class="col-md-12" style="text-align: center">
    <table class="table table-hover">
        <caption>共${page.totalQuantity}篇博客</caption>
        <thead>
        </thead>
        <tbody>
        <c:forEach items="${blogList}" var="blog" varStatus="status">
            <tr>
                <td style="width: 60%;height: 100px">
                    <a href="showBlog.jsp?blogId=${blog.blogId}" style="text-decoration: none;font-size:25px;font-weight:bold;">${blog.title}</a>
                </td>
                <td style="width: 20%;height: 100px;padding-top:80px">${blog.author}</td>
                <td style="width: 20%;height: 100px;padding-top:80px">${blog.createTime}</td>
            </tr>
        </c:forEach>
        </tbody>
    </table>
</div>
    <div style="width:100%;padding-left: 48vw">
        <ul class="pagination">
            <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
                <a href="?page.startIndex=0" style="text-decoration: none;font-size:20px;font-weight:bold;">
                    <span>«</span>
                </a>
            </li>
            <li <c:if test="${!page.hasPreviouse}">class="disabled"</c:if>>
                <a href="?page.startIndex=${page.startIndex-page.perPageQuantity}" style="text-decoration: none;font-size:20px;font-weight:bold;margin-left: 10px">
                    <span></span>
                </a>
            </li>
            <c:forEach begin="0" end="${page.totalPage-1}" varStatus="status">

                <c:if test="${status.count*page.perPageQuantity-page.startIndex<=30 && status.count*page.perPageQuantity-page.startIndex>=-10}">
                    <li <c:if test="${status.index*page.perPageQuantity==page.startIndex}">class="disabled"</c:if>>
                        <a href="?page.startIndex=${status.index*page.perPageQuantity}" style="text-decoration: none;font-size:20px;font-weight:bold;margin-left: 10px"
                                <c:if test="${status.index*page.perPageQuantity==page.startIndex}">class="current"</c:if>
                        >${status.count}</a>
                    </li>
                </c:if>
            </c:forEach>

            <li>
                <a href="?page.startIndex=${page.startIndex+page.perPageQuantity}" style="text-decoration: none;font-size:20px;font-weight:bold;margin-left: 10px">
                    <span></span>
                </a>
            </li>
            <li>
                <a href="?page.startIndex=${page.last}" style="text-decoration: none;font-size:20px;font-weight:bold;margin-left: 10px">
                    <span>»</span>
                </a>
            </li>
        </ul>
    </div>
</div>
</body>
<script>
    $(function () {
        //禁用分页按钮的函数
        $("ul.pagination li.disabled a").click(function () {
            return false;
        });
    });
</script>
</html>

效果图:
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

点击标题进入到博客内容展示页(showBlog.jsp),可以看到详细的博客内容

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap5/css/bootstrap.min.css"> 
    <script src="bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <link href="css/myStyle.css"  rel="stylesheet">

    <link rel="stylesheet" href="editorMd/css/editormd.min.css"/>
<%--    <link rel="stylesheet" href="editorMd/css/editormd.css"/>--%>


</head>
<body>
<%@ include file="header.jsp"%>
<div style="text-align: center">
    <h2 id="title">hhh</h2>
    <p style="text-align: right">
        <span id="author" style="margin-right: 20px">asdfuhiod</span>
        <span id="time" style="margin-right: 100px">fffff</span>
    </p>

</div>
<div id="test-editormd" style="width: 90%;padding-left: 5%" >
    <textarea style="display: none" id="test-editormd-markdown-doc" name="test-editormd-markdown-doc">这篇博客
</textarea>
</div>

</body>
<script src="editorMd/editormd.min.js"></script>
<script src="editorMd/lib/marked.min.js"></script>
<script src="editorMd/lib/prettify.min.js"></script>
<script src="editorMd/lib/raphael.min.js"></script>
<script src="editorMd/lib/underscore.min.js"></script>
<script src="editorMd/lib/sequence-diagram.min.js"></script>
<script src="editorMd/lib/flowchart.min.js"></script>
<script src="editorMd/lib/jquery.flowchart.min.js"></script>
<script type="text/javascript">
    var testEditor;
    //得到后端传来的md格式的文章
   function getBlogContent(){
       // 用=将路由参数分割成数组
       let idArray = window.location.search.split('=');
       //console.log(idArray);
       // 获取路由的参数
       var blogId = idArray[1];

        $.ajax({
            url:"${pageContext.request.contextPath}/blog",//这个url是处理请求的servlet的url
            type:"GET",
            data: { "method":"blogDisplay","blogId":blogId},
            dataType:"json",
            success:function (data,status){
                document.getElementById("title").innerText = data.title;
                document.getElementById("author").innerText = data.author;
                document.getElementById("time").innerText = data.createTime;
                //console.log("data"+ data.blogContent);
                var text = document.getElementById("test-editormd-markdown-doc");
                    text.innerHTML = data.blogContent;//不可用innerText
                    showBlog();

            },error:function (status){
                console.log(status);
            }
        });
    }

    //DOM加载完成后执行上面函数,将文章内容放到textarea内,并用editormd进行处理、展示
    $(document).ready(getBlogContent());

    function showBlog(){
        testEditor = editormd.markdownToHTML("test-editormd", {
            htmlDecode: "style, script, iframe",
            //width:"90%",
            //preview:true,
            //watch:true,
            emoji: true,
            taskList: true,
            tex: true,  // 默认不解析
            flowChart: true,  // 默认不解析
            sequenceDiagram: true,  // 默认不解析
        });
    }
</script>
</html>

效果图如下:
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

关于本站页面就是个简单的静态页面,内容基本就第四篇博客中的那些,这里就不赘述了。

点击右上角圆形头像展开提示菜单,可以选择“个人中心”、“发布博客”、“登录”、“退出”,如下图效果:
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

点击“个人中心”,触发登录验证,若没有登录则转向登录页面(login.jsp),登录成功后转到个人中心(personalCenter.jsp)

登录页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset=UTF-8">
    <title>微光落尘的个人空间</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <script src="js/jquery-3.5.1.min.js"></script>
    <script src="js/bootstrap.min.js"></script>

    <style>
        .in_style{
            background-color:rgba(30,144,255,0.1);
            color:#1E90FF;
            border:1px solid #1E90FF
        }
        body{
            background:url("img/north-star-2869817_1920.jpg")  no-repeat center center;   /*加载背景图*/   /* 背景图不平铺 */
            background-size:cover;  /* 让背景图基于容器大小伸缩 */
            background-attachment:fixed;        /* 当内容高度大于图片高度时,背景图像的位置相对于viewport固定 */
            background-color:#CCCCCC;   /* 设置背景颜色,背景图加载过程中会显示背景色 */
        }
        .myBox{
            background-color: rgba(30,144,255,0.1);
            border:1px solid #1E90FF;
            border-radius: 10px;
        }

    </style>
</head>
<body>

<div class="text-center">
    <div class="container">
        <div class="row" style="margin-top:30vh;">
            <div class="col-sm-4 col-md-offset-8 myBox">
                <div class="row" style="margin-bottom: 5vh">
                    <h1 style="color: rgba(253,252,252,0.98)">小尘空间传送门</h1>
                </div>
                <form  id="form1" class="bs-example bs-example-form" role="form" action="${pageContext.request.contextPath}/login" method="post">
<%--                    登录失败提示信息--%>
                    <div class="info" style="color:red">${error}</div>
                    <div class="input-group" >
                        <span class="input-group-addon control-label in_style">时空节点</span>
                        <input type="text" id="username" name="username" class="form-control in_style" placeholder="">
                    </div>
                    <br>
                    <div class="input-group" style="margin-top:10px">
                        <span class="input-group-addon control-label in_style">开启秘钥</span>
                        <input type="password" name="password" class="form-control in_style" placeholder="">
                    </div>
                    <br>
                    <div class="input-group-btn" style="padding-top:3vh;padding-bottom: 1vh;text-align: end">
                        <input type="submit" id="login" class="btn btn-default" style="border:none;background-color: rgba(30,144,255,0.4);color: #1E90FF">点击传送</input>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
</body>
</html>

效果图如下:
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

个人中心(personalCenter.jsp),这页其实也只是拿来充门面的:

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="../bootstrap5/css/bootstrap.min.css">
    <script src="../bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="../js/jquery-3.5.1.min.js"></script>
    <link href="../css/myStyle.css" rel="stylesheet">

</head>
<body>
<div class="row">
    <%@ include file="left.jsp"%>

<div class="col-md-9" style="text-align: center;margin-left:300px">
    <img src="../img/north-star-2869817_1920.jpg" alt="mdo" width="100" height="100" class="rounded-circle" style="margin-top:10vh">
    <from>
        <div class="row">
            <div class="col-md-1 col-offset-1" style="margin-top:22px;margin-left: 10vw;">昵称:
            </div>
            <div class="col-md-8">
                <input type="text" class="form-control mt-3" value="微光落尘" readonly>
            </div>
        </div>
        <div class="row">
            <div class="col-md-1" style="margin-top:22px;margin-left: 10vw;">个性签名:
            </div>
            <div class="col-md-8">
                <input type="text" class="form-control mt-3"  value="可惜一溪风月,莫教踏碎琼瑶" readonly>
            </div>
        </div>
        <div class="row">
            <div class="col-md-1" style="margin-top:22px;margin-left: 10vw;">邮箱:
            </div>
            <div class="col-md-8">
                <input type="text" class="form-control mt-3" value="1054553042@qq.com" readonly>
            </div>
        </div>

    </from>
</div>
</div>
</body>

<script type="text/javascript">
</script>
</html>

自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

点击左侧导航栏“博客管理”,进入博客管理页面(blogManagement.jsp),可以选择修改和删除博客,也是本系统的核心,这里的动态列表使用js动态生成的(别问我这里为什么不用jstl,jstl真的简单些…)

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="../bootstrap5/css/bootstrap.min.css">
    <script src="../bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="../js/jquery-3.5.1.min.js"></script>
    <link href="../css/myStyle.css"  rel="stylesheet">

</head>
<body>
<div class="row" style="height: 100%">
    <%@ include file="left.jsp"%>
    <div class="col-md-9" id="blogList" name="blogList" style="margin-left: 300px">
    </div>
</div>
</body>

<script type="text/javascript">
    $(document).ready(function (){
        $.ajax({
            url:"${pageContext.request.contextPath}/blog",//这个url是处理请求的servlet的url
            type:"POST",
            data: {"method":"getAllBlog"},
            dataType:"json",
            success:function (data,status){
                //console.log("data"+ JSON.stringify(data));
                //console.log(status);
                generateBlogList(data);

            },error:function (status){
                console.log(status);
            }
        });
    })

//下面是生成动态列表的函数,主要是循环创建具有层次的节点,把数据填充进去
    function generateBlogList(blogList){
        var list = document.getElementById("blogList");
        for(let i = 0;i<blogList.length;i++){
            let blogItem = document.createElement("div");
            blogItem.setAttribute("class","row");
            blogItem.style.cssText = "border-bottom: 1px solid black;height: 100px;";



            let adiv = document.createElement("div");
            adiv.setAttribute("class","col-md-6");
            let blogTitle = document.createElement("a");
            blogTitle.setAttribute("href","${pageContext.request.contextPath}/showBlog.jsp?blogId="+blogList[i].blogId);
            blogTitle.style.cssText="text-decoration: none;font-size:25px;font-weight:bold;"
            blogTitle.innerText = blogList[i].title;
            adiv.appendChild(blogTitle)
            blogItem.appendChild(adiv)

            let divTwo = document.createElement("div");
            divTwo.setAttribute("class","col-md-2");
            let blogAuthor = document.createElement("span");
            blogAuthor.style.cssText="margin-top:80px"
            blogAuthor.innerText = blogList[i].author;
            divTwo.appendChild(blogAuthor)
            blogItem.appendChild(divTwo);

            let divThree = document.createElement("div")
            divThree.setAttribute("class","col-md-2");
            let blogCreateTime = document.createElement("span");
            blogCreateTime.style.cssText="margin-top:80px"
            blogCreateTime.innerText = blogList[i].createTime;
            divThree.appendChild(blogCreateTime)
            blogItem.appendChild(divThree);


            let divFour = document.createElement("div");
            divFour.setAttribute("class","col-md-2");
            let buttonOne = document.createElement("button");
            buttonOne.setAttribute("class","btn btn-success");
            buttonOne.setAttribute("id","edit");
            buttonOne.setAttribute("onclick","toEditPage("+blogList[i].blogId+")");
            buttonOne.innerText="编辑";
            divFour.appendChild(buttonOne);
            let buttonTwo = document.createElement("button");
            buttonTwo.setAttribute("class","btn btn-danger");
            buttonTwo.setAttribute("id","delete");
            buttonTwo.setAttribute("onclick","deleteBlog("+blogList[i].blogId+")");
            buttonTwo.innerText="删除";
            divFour.appendChild(buttonTwo);
            blogItem.appendChild(divFour);

            list.appendChild(blogItem);
        }
    }

//跳转到文章对应的编辑页面
    function toEditPage(blogId){
        window.location.href="../editBlog.jsp?blogId="+blogId;
    }

//点击删除按钮的事件处理函数
    function deleteBlog(blogId){
        if(confirm("确定删除这篇博客?") == false){
            return;
        }
        $.ajax({
            url:"${pageContext.request.contextPath}/blog",//这个url是处理请求的servlet的url
            type:"POST",
            data: {"method":"delete",
                "blogId":blogId},
            dataType:"json",
            success:function (data,status){
                // console.log("data"+ JSON.stringify(data));
                // console.log(status)
                if(data.result === "success"){
                    location.reload();
                    alert("已删除");
                }else{
                    alert("出错了");
                }
            },error:function (status){
                console.log(status);
                alert("出错了");
            }
        });
    }
</script>

</html>

自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
点击编辑,可以修改博客内容,顺便一说,因为是个人博客系统,所以作者也被我写成默认的了(不是偷懒啊…)

博客编辑页面(editBlog.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="bootstrap5/css/bootstrap.min.css">
    <script src="bootstrap5/js/bootstrap.bundle.min.js"></script>
    <title>微光落尘的个人空间</title>
    <script src="js/jquery-3.5.1.min.js"></script>
    <link href="css/myStyle.css"  rel="stylesheet">

    <link rel="stylesheet" href="editorMd/css/editormd.min.css">
    <script src="editorMd/editormd.min.js"></script>

</head>
<body>
<%@ include file="header.jsp"%>

<div class="row">
    <div id="topbar" name="topbar" class="col-sm-1 p-3" style="margin-top: 6px;text-align: center;font-weight: bold;font-size: 20px" >
        <a style="text-decoration: none" href="${pageContext.request.contextPath}/personalCenter/blogManagement.jsp">
            <img src="img/icons8-back-64.png" width="32" height="30">返回
        </a>
    </div>
    <div class="col-sm-8 p-3">
        <input type="text" id="title" name="title" class="form-control" style="font-weight: bold" placeholder="">
    </div>
    <div class="col-sm-1" style="padding-top: 12px;text-align: center">
        <button type="submit" id="publish" class="btn btn-info" onclick="modify()">发布</button>
    </div>
</div>
</div>

<div id="test-editor">
    <textarea id="test-editor-blogContent" name="test-editor-blogContent"></textarea>
    <br>
</div>

</body>
<script type="text/javascript">

    //得到后端传来的md格式的文章
    function prepareEditBlog(){
        // 用=将路由参数分割成数组
        let idArray = window.location.search.split('=');
        //console.log(idArray);
        // 获取路由的参数
        var blogId = idArray[1];
        $.ajax({
            url:"${pageContext.request.contextPath}/blog",//这个url是处理请求的servlet的url
            type:"GET",
            data: { "method":"blogDisplay","blogId":blogId},
            dataType:"json",
            success:function (data,status){
                //console.log("data"+ data.blogContent);
                var title = document.getElementById("title");
                title.value = data.title;
                var text = document.getElementById("test-editor-blogContent");
                text.innerHTML = data.blogContent;//不可用innerText
                //editBlog;//editormd处理

            },error:function (status){
                console.log(status);
            }
        });
    }

    //DOM加载完成后执行上面函数,将文章内容放到textarea内,并用editormd进行处理、展示
    $(document).ready(prepareEditBlog());


    function modify(){
        if(document.getElementById("title").value === "" ||document.getElementById("title").value == null){
            alert("请输入文章标题");
            return;
        }
        //编码后传输到后端
        var content = encodeURIComponent(editor.getMarkdown());
        //console.log(content);
        // 用=将路由参数分割成数组
        let idArray = window.location.search.split('=');
        //console.log(idArray);
        // 获取路由的参数
        var blogId = idArray[1];

        $.ajax({
            url:"${pageContext.request.contextPath}/blog",//这个url是处理请求的servlet的url
            type:"POST",
            data: {"method":"modify",
                "blogId":blogId,
                "title":document.getElementById("title").value,
                "blogContent":content},//document.getElementById("test-editor-blogContent").innerText
            dataType:"json",
            success:function (data,status){
                // console.log("data"+ JSON.stringify(data));
                // console.log(status)
                if(status === "success"){
                    alert("文章发布成功");
                }
            },error:function (status){
                console.log(status);
                alert("出错了");
            }
        });
    }


    var editor;
    $(function editBlog() {
        editor = editormd("test-editor", {
            // 在页面显示的宽度
            width   : "100%",
            // 高度
            height  : 400,
            path   : "editorMd/lib/"
        });
    });

</script>
</html>

自己动手搭网站(六):javaweb搭建一个简单的个人博客系统

发布博客页面(publish.jsp)和编辑页面差不多,就不多说了。

3、后端

后端整体结构和上篇说的一样,下面是后端的文件结构
自己动手搭网站(六):javaweb搭建一个简单的个人博客系统
后端具体的代码就不再罗列了,要完整代码的到我的gitee仓库下载即可,下面简单介绍下后端的一些重点内容。

servlet

两类servlet,分别用来处理登录和博客管理相关的请求,登录上篇说得差不多了,博客管理相关的servlet主要有下面几个函数

        String method = req.getParameter("method");
        if(method.equals("publish")){//用户写完博客点击发布后触发的函数,也就是添加博客到数据库中
            this.publish(req,resp);
        } else if (method.equals("getAllBlog")){//从数据库中取出所有博客
            this.getAllBlog(req,resp);
        }else if(method.equals("delete")){//删除博客
            this.deleteBlog(req,resp);
        }else if(method.equals("modify")){//修改博客
            this.modify(req,resp);
        }else if(method.equals("blogDisplay")){//博客展示,用户点击标题后触发的请求
            this.queryBlogById(req,resp);
        }
    }

还有一个专门用于辅助分页展示的servlet,关于分页功能,这篇文章讲的比较详细,大家可以参考下
Java Web -【分页功能】详解

登录功能已经在上篇中说过,这里不再赘述。

service层

这层主要是处理一些业务逻辑,并调用数据访问层进行进一步处理,以添加博客功能为例,代码如下

    @Override
    public boolean addBlog(String author, String title, String content) {
    //返回给servlet的状态标识,用以表示操作是否成功
        boolean flag = false;

        Connection connection = null;//数据库连接
        //获取时间并格式化
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = format.format(date);
        String updateTime = createTime;

//连接数据库,并执行添加博客的操作
        try {
            connection = BaseDao.getConnection();
            flag = blogdao.addBlog(connection,author,title,content,createTime,updateTime);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
        //关闭连接
            BaseDao.closeResourse(connection,null,null);
        }
        return flag;
    }

其它函数也差不多是这个逻辑,这里页不再赘述

dao层

数据访问层,一些基本的内容在上篇中也已经谈到,一般我们会把基本的数据库操作封装到一起,命名为BaseDao,其它Dao调用BaseDao的函数。仍然以添加博客为例,简单介绍下

    @Override
    public boolean addBlog(Connection connection,String author,String title, String content, String createTime, String updateTime) {
        boolean flag = false;//返回给上层的表示,表示操作是否成功

        PreparedStatement pstm = null;//预编译的sql语句
        ResultSet result = null;//执行操作得到的结果集
        int res;//执行操作得到的数据库返回的状态码,一般是受影响的行数,不过在mysql中可能是匹配的行数

        if(connection != null) {
            String sql = "insert into blog(author,title,content,create_time,update_time,is_deleted) values(?,?,?,?,?,?)";
            //is_deleted默认为0,表示博客未被删除
            Object[] params = {author,title,content,createTime,updateTime,0};//上面sql语句需要的参数

//执行数据更新操作
            try {
                res = BaseDao.update(connection, sql, result, pstm, params);
                if (res == 1) {
                    flag = true;
                }
                //关闭资源
                BaseDao.closeResourse(null, result, pstm);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return flag;
    }

配置文件

主要是网站配置文件web.xml、数据库配置文件按db.properties和maven配置文件pom.xml
web.xml文件主要是声明过滤器和servlet,设置网站首页

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1"
         metadata-complete="true">

<!--  设置访问首页-->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
<!--  servlet声明 -->
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.shimmer.servlet.user.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>BlogServlet</servlet-name>
    <servlet-class>com.shimmer.servlet.blog.BlogServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>BlogServlet</servlet-name>
    <url-pattern>/blog</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>PagingServlet</servlet-name>
    <servlet-class>com.shimmer.servlet.blog.PagingServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PagingServlet</servlet-name>
    <url-pattern>/paging</url-pattern>
  </servlet-mapping>

  <!--字符编码过滤器-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>com.shimmer.filter.CharacterEncodingFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.shimmer.filter.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/personalCenter/*</url-pattern>
  </filter-mapping>

</web-app>

db.properties配置数据库连接必要信息

//driver是驱动
driver=com.mysql.cj.jdbc.Driver 
//mysql后是MySQL服务器IP和端口,再后面是数据库名字,再是一些配置
url=jdbc:mysql://127.0.0.1:3306/blog_system?useUnicode=true&characterEncoding=utf-8&userSSL=false&serverTimezone=GMT%2B8
username=自己设的
password=自己设置的

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>MyBlogSystem</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>


  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.29</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.79</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
  
</project>

到这里,这个系统基本就介绍得差不多了,可能讲解的不是很详细,不过篇幅已经够长了(主要是博主快编不动了…)若有不清晰的地方,大家可以参考后面参考资料中的文章、视频等再研究研究。整个《自己动手搭网站》系列到此暂且也算是结束第一期了。虽然,部署维护什么的只是稍微提及,等后面有空再补上吧(等我学会再来编…)。

另外,功能方面做得比较简陋是因为考虑到后面可能升级到spring boot+vue的技术栈,spring+前端的模式也是目前比较主流的web技术栈之一,这套技术怎么说呢,其实也是从J2EE简化扩展来的,有了javaweb的基础后,springboot上手还是比较快的,但想深入了解,可能就非一时之功了。另外,前端框架的学习可能要稍微多花些功夫,虽然有现成的样式可以参考(ElementUI),但是要灵活使用还是比较困难的,这也是博主没有一次性跨到这套技术栈的原因,步子太大了,容易那啥来着…

最后,如果觉得本篇文章对您有帮助的话,别忘了点赞!!!

参考资料

1、菜鸟-Bootstrap5 教程
2、editor.md官网
3、富文本编辑器Editor.md入门
4、javaweb从入门到实战
5、Java Web -【分页功能】详解文章来源地址https://www.toymoban.com/news/detail-466458.html

到了这里,关于自己动手搭网站(六):javaweb搭建一个简单的个人博客系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于Hugo 搭建个人博客网站

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

    2024年02月09日
    浏览(53)
  • 手把手教你实现一个JavaWeb项目:创建一个自己的网页博客系统(前端+后端)(一)

    一篇博客带你实现一个真正的项目!  先来看看它是什么样式的: 目录: 1、大体步骤🦖:         1、创建Maven项目🦕         2、引入依赖🦕         3、创建必要的目录🦕         4、编写代码🦕         5、打包部署(基于SmartTomcat)🦕         

    2024年02月06日
    浏览(57)
  • Hexo+GithubPages免费搭建个人博客网站

    一、前言 二、Github配置 新建同名仓库 配置Pages 三、安装Hexo 四、配置hexo-deployer-git 五、访问 六、发布文章 七、安装主题 我之前开了好几年的云服务器了,实际上使用场景并不是很多,感觉有点浪费。前两个月都给关掉了,现在呢琢磨着弄一个免费的云服务搭建个人博客。

    2024年02月13日
    浏览(56)
  • 【Zblog搭建博客网站】windows环境搭建属于自己的博客并发布上线

    转载自cpolar极点云文章:【Zblog建站】搭建属于自己的博客网站,并内网穿透实现公网访问 想要成为一个合格的技术宅或程序员,自己搭建网站制作网页是绕不开的项目。就以笔者自己的经历来说,就被自制网页网站卡过很久。不过随着电脑技术的发展,已经出现了很多便捷

    2024年02月15日
    浏览(46)
  • 使用宝塔面板搭建个人网站(博客)超详细2023

    提示:这里可以添加本文要记录的大概内容: 一直有一个执念想搭一个自己的网站,今天才付出行动,分享给同样想法的鼠鼠 个人网站地址:https://ooooooooooooooooooooooo.ooo/ooooοооoοᴏοoοᴏοoοᴏoooᴏооoоᴏᴏoоᴏᴏoᴏοοoᴏoooоᴏоoᴏоοoᴏoᴏoоᴏоoᴏoоoᴏoooᴏοοoоᴏоoᴏ

    2024年02月14日
    浏览(54)
  • Astro + Vercel 快速搭建自己的博客网站

    Astro 和 Vercel 彼此相得益彰,前者提供出色的开发者体验,用于构建现代静态站点,而后者负责部署和托管代码。 两者结合我们就可以轻轻松松 零成本 搭建自己的博客网站。查看示例。 如果对原项目感兴趣,可以查看源码。 在部署博客之前,我们先创建一个用于评论的 g

    2024年02月14日
    浏览(33)
  • 如何使用Jekyll在GitHub Pages上搭建网站(个人博客)

    本文很长,建议使用侧边栏进行跳转。 Jekyll 是一个基于 Ruby 语言的,用于搭建静态网站的生成器,主要用于搭建博客网站(官方自己的介绍为:Jekyll is a blog-aware, static site generator in Ruby)。但是虽然是静态网站,但是可以实现一些使用数据库的动态网站的效果和功能,是很不

    2024年02月06日
    浏览(83)
  • 使用 腾讯云搭建一个个人博客

    腾讯云:CPU: 2核 内存: 4GB系统盘60GB (带宽:6Mbps) LNMP:1.5 WORDPRESS:5.92 一个专属的域名 买了服务器后,你就会拥有一个公网ip,如果网站搭建起来了,你完全可以使用这个 ip 去访问,但仅供开发、测试使用。 如果要真正运营起来,想要有流量,还得搞一个域名,方便你推

    2023年04月08日
    浏览(31)
  • 个人博客网站一揽子:Docker搭建图床(Lsky Pro)

    Lsky Pro 介绍 Lsky Pro 是一个用于在线上传、管理图片的图床程序,中文名:兰空图床,你可以将它作为自己的云上相册,亦可以当作你的写作贴图库。 兰空图床始于 2017 年 10 月,最早的版本由 ThinkPHP 5 开发,后又经历了数个版本的迭代,在 2021 年末启动了新的重写计划并于

    2024年02月05日
    浏览(52)
  • 免费搭建个人博客:零成本实现网站发布,无需域名和服务器

    估计每个开发者想拥有属于自己的个性化博客网站,但却担心域名和服务器费用 还有那些头痛的服务器费配置,现在我们可以可以在几分钟内拥有的博客网站,并且无需支付任何域名和服务器费用 本文推荐的建站方案核心就是:hugo  Hugo,一个快速、简单且功能强大的静态网站生

    2024年04月26日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包