实现博客系统2

简介: 实现博客系统

实现博客系统1:https://developer.aliyun.com/article/1521719

3、实现登录页

约定前后端交互接口

使用form表单来进行提交

//请求
POST/login
Content-Type:application/x-www-form-urlencoded
username=?&password=?
//响应
HTTP/1.1 302
Location:blog_list.html

服务器端

先将请求和响应都按照utf8进行解析避免出现乱码,然后获取到请求中的userName和password判断是否与数据库匹配,若匹配就创建会话跳转到博客列表页。

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        resp.setCharacterEncoding("utf8");
        resp.setContentType("text/html;charset=utf8");
        String userName = req.getParameter("userName");
        String password = req.getParameter("password");
        if(userName == null || "".equals(userName) || password == null || "".equals(password)){
            resp.getWriter().write("用户名或密码不能为空");
            return;
        }
        UserDAO userDAO = new UserDAO();
        User user = userDAO.getUserByName(userName);
        if(user != null && user.getPassword().equals(password)){
            //创建会话
            HttpSession session = req.getSession(true);
            //将信息存储到绘画中
            session.setAttribute("user",user);
            //返回重定向报文,跳转到详情页
            resp.sendRedirect("blog-list.html");
        }else{
            resp.getWriter().write("用户名或密码错误");
        }
    }
}

客户端

利用form表单进行提交。

<form action="login" method="post">
    <div class="row">
        <span>用户名</span>
        <span><input  class="input" type="text" name="userName"></span>
    </div>
    <div class="row">
        <span>密码</span>
        <span><input  class="input" type="password" name="password"></span>
    </div>
    <div class="submit">
        <input type="submit" id="submit" value="提交">
    </div>
</form>

4、实现强制要求登陆

对于博客列表页和博客详情页等都需要在登录成功的基础上来进行后序的操作。

约定前后端交互接口

登录状态就返回当前用户的信息,未登录就返回userId为0的对象。

//请求
GET/login
//响应
HTTP/1.1 200 OK
Content-Type:application/json
{
    userId:xx,
    userName
}


服务器端

先判断是否创建会话,再判断会话中是否存在user对象,两种情况等都满足表示已经登录,否则就是未登录状态。

//获取当前的登录状态
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        resp.setContentType("application/json;charset=utf8");
        HttpSession session = req.getSession(false);
        User user = new User();
        if(session == null){
            //未创建会话,表示未登录
            resp.getWriter().write(objectMapper.writeValueAsString(user));
            return;
        }
        user = (User)session.getAttribute("user");
        if(user == null){
            //会话中没有user对象
            user = new User();
            resp.getWriter().write(objectMapper.writeValueAsString(user));
            return;
        }
        //将密码信息不返回给前端
        user.setPassword("");
        resp.getWriter().write(objectMapper.writeValueAsString(user));
    }


客户端

在博客列表页和详情页等加入该方法来判断是否登录,若未登录就跳转到登录页面进行登录。

//获取当前登录状态
        function getUserInfo(pageName){
            $.ajax({
                type:'get',
                url:'login',
                success:function(body){
                    //判定body中的user对象是否有效
                    if(body.userId && body.userId > 0){
                        //表示登录成功,暂时不做处理
                    }else{
                        alert("您当前尚未登录");
                        //跳转到登录页
                        location.assign('blog-login.html');
                    }
                },
                error:function(){
                    alert("您当前尚未登录");
                    //跳转到登录页
                    location.assign('blog-login.html');
                }
            });
        }

5、实现显示用户信息

在登录之后,博客详情页能显示当前作者的个人信息。

进入博客详情页之后能显示作者的个人信息。  

约定前后端交互接口

//请求
GET/user
//响应
{
    userId:xx,
    userName:xxx
    
}
//请求
GET/user?userId=xx
//响应
{
    userId:xx,
    userName:xxx
    
}

服务器端

在数据库中先得到当前博客的id,再获取到其作者信息。

@WebServlet("/authorInfo")
public class AuthorServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
        //获取到指定博客的作者信息
        String param = req.getParameter("blogId");
        if (param == null || "".equals(param)) {
            resp.getWriter().write("{\"ok\":false,\"reason:\":\"参数缺失!\"}");
            return;
        }
        BlogDAO blogDAO = new BlogDAO();
        Blog blog = blogDAO.getBlog(Integer.parseInt(param));
        if(blog == null){
            resp.getWriter().write("{\"ok\":false,\"reason:\":\"要查询的博客不存在!\"}");
            return;
        }
        UserDAO userDAO = new UserDAO();
        User author = userDAO.getUserById(blog.getUserId());
        if(author == null){
            resp.getWriter().write("{\"ok\":false,\"reason:\":\"要查询的用户不存在!\"}");
            return;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        author.setPassword("");
        resp.getWriter().write(objectMapper.writeValueAsString(author));
    }
}


客户端

只需要在登录成功时将用户名改成当前登录的用户名。

function changeUserName(userName){
        let h3 = document.querySelector('.card>h3');
        h3.innerHTML = userName;
    }

在进入博客列表详情页时显示作者名。

 function getAuthorInfo(user){
        $.ajax({
            type:'get',
            url:'authorInfo'+location.search,
            success:function(body){
                if(body.userName){
                    changeUserName(body.userName);
                }else{
                    alert("获取作者信息失败")
                }
            },
            error:function(){
                alert("获取作者信息失败")
            }
        });
    }

6、实现发布博客

实现前后端交互接口

//请求
POST/blog
Content-Type:application/x-www-form-urlencoded
//响应
HTTP/1.1 302
Location:blog_list.html


服务器端

先确保用户是登录状态,然后再确认发表的博客标题和内容都不能为空,然后将发表的博客插入到数据库中,页面跳转到博客列表页。

//发表博客
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        resp.setCharacterEncoding("utf8");
        resp.setContentType("text/html;charset=utf8");
        ObjectMapper objectMapper = new ObjectMapper();
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.getWriter().write("用户未登录");
            return;
        }
        User user = (User)session.getAttribute("user");
        if(user == null){
            resp.getWriter().write("用户未登录");
            return;
        }
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if(title == null || "".equals(title) || content == null || "".equals(title)){
            resp.getWriter().write("提交博客失败,缺少博客标题或内容");
            return;
        }
        Blog blog = new Blog();
        blog.setUserId(user.getUserId());
        blog.setTitle(title);
        blog.setContent(content);
        BlogDAO blogDAO = new BlogDAO();
        try {
            blogDAO.addBlog(blog);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.sendRedirect("blog-list.html");
    }

客户端

利用form表单将内容进行提交。

<form action="blog" method="post" style="height:100%">
            <div class="title">
                <input type="text" placeholder="在此处输入标题" name="title" id="title">
                <!-- <button>发布文章</button> -->
                <input type="submit" value="发布文章" id="submit">
            </div>
            <!-- 放置 md 编辑器 -->
            <div id="editor">
                <!-- 为了进行 form 的提交, 此处搞一个 textarea 多行编辑框, 借助这个编辑框来实现表单的提交 -->
                <!-- 可以设置 editor.md, 让编辑器把 markdown 内容也同步的保存到这个隐藏的 textarea 中, 从而可以进行 form 提交 -->
                <textarea name="content" style="display:none"></textarea>
            </div>
</form>

7、删除博客

约定前后端交互接口

//请求
GET/user?blogId=x
//响应
{
userId:xx;
userName:xxx;
isYourBlog: 1,  // 1 表示当前博客就是登陆者的博客. 0 表示当前博客不是登陆者的博客. 
}

服务器端

先判断当是否为登录状态,然后判断当前作者与登录用户是否一致,若相同则在数据库中删除该博客,然后将页面跳转到博客列表页。

@WebServlet("/blogDelete")
public class DeleteBlogServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.getWriter().write("用户未登录");
            return;
        }
        User user = (User)session.getAttribute("user");
        if (user == null) {
            resp.getWriter().write("用户未登录");
            return;
        }
        String blogId = req.getParameter("blogId");
        if(blogId == null || "".equals(blogId)){
            resp.getWriter().write("博客编号有误");
            return;
        }
        BlogDAO blogDAO = new BlogDAO();
        Blog blog = blogDAO.getBlog(Integer.parseInt(blogId));
        if(blog == null || "".equals(blog)){
            resp.getWriter().write("待删除的博客不存在");
            return;
        }
        if(user.getUserId() != blog.getUserId()){
            resp.getWriter().write("不是本博客的作者,无法删除");
            return;
        }
        try {
            blogDAO.deleteBlog(Integer.parseInt(blogId));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.sendRedirect("blog-list.html");
    }
}

客户端

在列表详情页如果判断当前的作者是正在登录的用户,就新增一个删除超链接,可以进行删除。

function getAuthorInfo(user){
        $.ajax({
            type:'get',
            url:'authorInfo'+location.search,
            success:function(body){
                if(body.userName){
                    changeUserName(body.userName);
                    if(body.userName == user.userName){
                        let navDiv = document.querySelector('.nav');
                        let a = document.createElement('a');
                        a.innerHTML='删除';
                        a.href = 'blogDelete' +location.search;
                        navDiv.appendChild(a);
                    }
                }else{
                    alert("获取作者信息失败")
                }
            },
            error:function(){
                alert("获取作者信息失败")
            }
        });
    }

8、实现注销功能

约定前后端交互接口

//请求
GET/logout
//响应
HTTP/1.1 302
Location:login.html

服务器端

先确认是否创建会话以确保登录状态,然后删除会话信息,并将登录的用户从数据库中删除,注销后跳转到登录页面。

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.getWriter().write("用户未登录");
            return;
        }
        User user = (User)session.getAttribute("user");
        //删除会话信息
        session.removeAttribute("user");
        UserDAO userDAO = new UserDAO();
        try {
            userDAO.deleteUser(user.getUserId());
            System.out.println(user.getUserId());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        resp.sendRedirect("blog-login.html");
    }
}


客户端

将注销超链接的href修改为logout。

<a href="logout">注销</a>

六、效果展示


目录
相关文章
|
存储 JavaScript 编译器
玩转vitepress1.0,搭建个人网站~
当初1月份的时候为了后续春招求职,就使用vitepress搭建了一个个人网站,然后把自己本地的一些md文件整理了发布在了上面,不过当时vitepress还未发布正式版本,还是0.22.x这样的版本, 所以其实有很多不满意的地方,比如侧边栏折叠之前没有,明暗模式之前没有,单篇文章的大纲好像也没有,侧边栏在不同tab下有问题,这些我不太确定,可能功能是有的,但是官方文档上没更新罢了
440 0
|
29天前
|
JSON 前端开发 Java
实现博客系统1
实现博客系统
21 0
实现博客系统1
|
9天前
|
缓存 关系型数据库 MySQL
Thinkphp5技术交流分享个人博客网站源码
Thinkphp5技术交流分享个人博客网站源码
14 0
|
1月前
|
关系型数据库 MySQL PHP
wordpress博客系统详细安装部署教程
wordpress博客系统详细安装部署教程
wordpress博客系统详细安装部署教程
|
11月前
|
前端开发
博客系统开发日记
2.如何去除Bootstarp栅格系统默认的15px的padding:https://blog.csdn.net/TsuiXh/article/details/93891357
70 0
|
前端开发 JavaScript
JavaWeb博客系统
JavaWeb博客系统
97 0
|
NoSQL 数据可视化 MongoDB
简易博客系统
整个项目在Visual Studio Code中完成,先要在该软件的终端启动服务器,其次要打开Windows上的cmd启动mongodb数据库,连接成功后,打开浏览器输入启动端口http://127.0.0.1:3007,进入首页,会展示所有用户发布的文章
228 0
简易博客系统
|
JSON 前端开发 JavaScript
【JavaWeb项目】博客系统
在网络学完HTTP协议,前端学完html,css,js,后端学完Servlet开发后,做一个博客系统,巩固一下所学知识,并将所学知识运用到实际当中,以此来进一步提升对学习编程的兴趣
【JavaWeb项目】博客系统
|
数据库 数据库管理
搭建 Zblog 博客系统-4
搭建 Zblog 博客系统-4
110 0
搭建 Zblog 博客系统-4