使用Servlet和JDBC编程来实现一个简单的博客系统(2)

 五.进行前后端接口设计(基于HTTP基础上进行扩展) 

  1. 获取注册页面   
  • 请求:GET/register.html
  • 响应:注册页面,页面上带有两个输入框(用户名和密码),还有一个提交按钮。 
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>注册</title>
    </head>
    <body>
    <form action="register" method="post">
        <input type="text" name="name" placeholder="请输入用户名">
        <br/>
        <input type="password" name="password" placeholder="请输入密码">
        <br/>
        <input type="submit" value="注册">
    </form>
    </body>
    </html>

     2.实现注册功能

  •  请求:POST/register
  • 响应:返回一个提示页面,告诉用户注册成功或失败,并能跳转到登陆页面。
    package api;
    
    import model.User;
    import model.UserDao;
    import view.HtmlGenerator;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class RegisterServlet extends HttpServlet {
        // 浏览器是通过 POST 方法提交注册信息给服务器的.
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=utf-8");
            // 1. 获取到前端提交的数据(用户名, 密码), 校验是否合法.
            String name = req.getParameter("name");
            String password = req.getParameter("password");
            if (name == null || "".equals(name)
                    || password == null || "".equals(password)) {
                // 用户提交的数据有误.
                // 返回一个错误页面. (一段字符串, html 构成得到)
                //"用户名或者密码为空"是页面中的提示信息,"register.html"表示接下来要跳转到哪里去
                String html = HtmlGenerator.getMessagePage("用户名或者密码为空",
                        "register.html");
                resp.getWriter().write(html);
                return;
            }
            // 2. 拿着用户名在数据库中查一下, 看看当前用户名是否已经存在. 如果存在, 认为注册失败(用户名不能重复)
            UserDao userDao = new UserDao();
            User existUser = userDao.selectByName(name);
            if (existUser != null) {
                // existUser 非空, 说明该用户名已经存在. 就提示用户, 注册失败, 用户名重复
                String html = HtmlGenerator.getMessagePage("用户名重复! 请换个名字!",
                        "register.html");
                resp.getWriter().write(html);
                return;
            }
            // 3. 根据前端提交的数据, 构造 User 对象并插入到数据库中.
            User user = new User();
            user.setName(name);
            user.setPassword(password);
            userDao.add(user);
            // 4. 返回一个结果页面, 提示当前注册成功.
            String html = HtmlGenerator.getMessagePage("注册成功! 点击跳转到登陆页面!",
                    "login.html");
            resp.getWriter().write(html);
        }
        }
    

     3.获取登陆页面 

  •  请求:GET/login.html
  • 响应:返回一个登陆页面,包含两个输入框和一个登陆按钮。
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>登录</title>
    </head>
    <body>
    <form action="login" method="post">
        <input type="text" name="name" placeholder="请输入用户名">
        <br/>
        <input type="password" name="password" placeholder="请输入密码">
        <br/>
        <input type="submit" value="登录">
    </form>
    </body>
    </html>

     4.实现登录功能 

  • 请求:POST/login
  • 响应:返回一个提示页面,告诉用户登陆成功或失败。 
    package api;
    
    import model.User;
    import model.UserDao;
    import view.HtmlGenerator;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    
    public class LoginServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=utf-8");
            // 1. 获取到用户名和密码. 并进行简单校验
            String name = req.getParameter("name");
            String password = req.getParameter("password");
            if (name == null || "".equals(name) || password == null || "".equals(password)) {
                String html = HtmlGenerator.getMessagePage("用户名或密码为空","login.html");
                resp.getWriter().write(html);
                return;
            }
            // 2. 数据库中查找, 看用户是否存在.
            // 3. 对比密码是否匹配
            UserDao userDao = new UserDao();
            User user = userDao.selectByName(name);
            if (user == null || !password.equals(user.getPassword())) {
                //用户不存在,提示错误
                String html = HtmlGenerator.getMessagePage("用户名或密码错误","login.html");
                resp.getWriter().write(html);
                return;
            }
            // 4. 匹配成功则认为登陆成功, 创建一个 Session
            HttpSession httpSession = req.getSession(true);
            httpSession.setAttribute("name",user);
            // 5. 返回一个登陆成功的提示页面
            String html = HtmlGenerator.getMessagePage("登陆成功","article");
            resp.getWriter().write(html);
        }
    }

     5.获取文章列表 

  • 请求:GET/article
  • 响应:返回文章的列表页(文章标题),点击标题进入详情页。 

     6.获取文章详细内容 

  • 请求:GET/article?article=1
  • 响应:返回文章的详情页(文章内容) 

     7.新增/发布文章 

  • 请求:POST/article/title=()&content=()
  • 响应:返回一个提示页面,告诉用户发布成功还是失败。 
    package api;
    
    import model.Article;
    import model.ArticleDao;
    import model.User;
    import model.UserDao;
    import view.HtmlGenerator;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    import java.util.List;
    
    
    public class ArticleServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=utf-8");
            // 1. 验证用户是否已经登陆了. 如果尚未登陆, 就提示用户要先登陆
            HttpSession httpSession = req.getSession(false);
            if (httpSession == null) {
                // 当前是未登录状态
                String html = HtmlGenerator.getMessagePage("请先登陆",
                        "login.html");
                resp.getWriter().write(html);
                return;
            }
            User user = (User) httpSession.getAttribute("user");
            // 2. 判断请求中是否存在 articleId 参数.
            String articleIdStr = req.getParameter("articleId");
            if (articleIdStr == null) {
                //  a) 没有这个参数就去执行获取文章列表操作
                getAllArticle(user, resp);
            } else {
                //  b) 有这个参数就去执行获取文章详情操作.
                getOneArticle(Integer.parseInt(articleIdStr), user, resp);
            }
        }
    
        private void getAllArticle(User user, HttpServletResponse resp) throws IOException {
            // 1. 查找数据库
            ArticleDao articleDao = new ArticleDao();
            List<Article> articles = articleDao.selectAll();
            // 2. 构造页面
            String html = HtmlGenerator.getArticleListPage(articles, user);
            resp.getWriter().write(html);
        }
    
        private void getOneArticle(int articleId, User user, HttpServletResponse resp) throws IOException {
            // 1. 查找数据库
            ArticleDao articleDao = new ArticleDao();
            Article article = articleDao.selectById(articleId);
            if (article == null) {
                // 文章未找到
                String html = HtmlGenerator.getMessagePage("文章不存在",
                        "article");
                resp.getWriter().write(html);
                return;
            }
    
            // 为了验证换行消失的问题, 在这个环节把 Article 中的正文打出来, 看看是不是带换行.
    //        System.out.println("article.content: " + article.getContent());
    
            // 2. 根据作者id 找到作者信息, 进一步得到作者姓名
            UserDao userDao = new UserDao();
            User author = userDao.selectById(article.getUserId());
            // 3. 构造页面
            String html = HtmlGenerator.getArticleDetailPage(article, user, author);
            resp.getWriter().write(html);
        }
    
        // 实现新增文章的逻辑
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("utf-8");
            resp.setContentType("text/html; charset=utf-8");
            // 1. 判定用户的登陆状态. 如果用户尚未登陆, 就要提示用户来登陆.
            HttpSession httpSession = req.getSession(false);
            if (httpSession == null) {
                String html = HtmlGenerator.getMessagePage("您尚未登陆",
                        "login.html");
                resp.getWriter().write(html);
                return;
            }
            User user = (User) httpSession.getAttribute("user");
            // 2. 从请求中读取浏览器提交的数据(title, content), 并进行简单校验
            String title = req.getParameter("title");
            String content = req.getParameter("content");
            if (title == null || "".equals(title)
                    || content == null || "".equals(content)) {
                String html = HtmlGenerator.getMessagePage("提交的标题或者正文为空",
                        "article");
                resp.getWriter().write(html);
                return;
            }
            // 3. 把数据插入到数据库中.
            ArticleDao articleDao = new ArticleDao();
            Article article = new Article();
            article.setTitle(title);
            article.setContent(content);
            article.setUserId(user.getUserId());
            articleDao.add(article);
            // 4. 返回一个插入成功的页面.
            String html = HtmlGenerator.getMessagePage("发布成功!",
                    "article");
            resp.getWriter().write(html);
            return;
        }
        }
    

     8.删除文章 

  • 请求:GET/deleteArticle?article=1
  • 响应:返回一个提示页面,告诉用户删除成功还是失败。 
    package api;
    
    import model.Article;
    import model.ArticleDao;
    import model.User;
    import view.HtmlGenerator;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    
    public class DeleteServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html; charset=utf-8");
            // 1. 验证用户的登陆状态, 如果未登陆, 肯定不能删除.
            HttpSession httpSession = req.getSession(false);
            if (httpSession == null) {
                String html = HtmlGenerator.getMessagePage("您尚未登陆!",
                        "login.html");
                resp.getWriter().write(html);
                return;
            }
            User user = (User) httpSession.getAttribute("user");
            // 2. 读取请求内容, 获取到要删除的文章 id
            String articleIdStr = req.getParameter("articleId");
            if (articleIdStr == null || "".equals(articleIdStr)) {
                String html = HtmlGenerator.getMessagePage("要删除的文章 id 有误",
                        "article");
                resp.getWriter().write(html);
                return;
            }
            // 3. 根据文章 id 查找到该文章的作者. 当前用户如果就是作者, 才能删除, 否则删除失败.
            ArticleDao articleDao = new ArticleDao();
            Article article = articleDao.selectById(Integer.parseInt(articleIdStr));
            if (article.getUserId() != user.getUserId()) {
                String html = HtmlGenerator.getMessagePage("您只能删除自己的文章!",
                        "article");
                resp.getWriter().write(html);
                return;
            }
            // 4. 真正执行数据库删除操作
            articleDao.delete(Integer.parseInt(articleIdStr));
            // 5. 返回一个 "删除成功" 的页面.
            String html = HtmlGenerator.getMessagePage("删除成功!",
                    "article");
            resp.getWriter().write(html);
        }
    }
    
    package view;
    
    import model.Article;
    import model.User;
    
    import java.util.List;
    
    
    public class HtmlGenerator {
        // 通过字符串拼接的形式, 构造出一个 html 格式的内容来.
        // 下面的代码实现起来非常麻烦. (HTML 嵌入到 Java 代码中)
        // 如果页面简单还好, 如果页面复杂, 那就非常不好整了.
        // 使用这种写法, 代码简单粗暴(不需要引入新的知识的)
        // 实际开发中还有更科学的写法:
        // 1. 服务器渲染页面, 把业务代码嵌入到 HTML (JSP, PHP);
        // 2. 服务器渲染页面, 把 HTML 嵌入到业务代码中, 不使用字符串拼接的方式,
        //    而是使用模板的方式. (FreeMarker)
        // 3. 前端渲染页面, 通过前后端分离的方式, 服务器只是返回简单数据, 由前端代码同过 JS
        //    构造页面内容. [主流]
        public static String getMessagePage(String message, String nextUrl) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("<html>");
            stringBuilder.append("<head>");
            stringBuilder.append("<meta charset=\"utf-8\">");
            stringBuilder.append("<title>提示页面</title>");
            stringBuilder.append("</head>");
            stringBuilder.append("<body>");
    
            stringBuilder.append("<h3>");
            stringBuilder.append(message);
            stringBuilder.append("</h3>");
    
            stringBuilder.append(String.format("<a href=\"%s\"> 点击这里进行跳转 </a>",
                    nextUrl));
    
            stringBuilder.append("</body>");
            stringBuilder.append("</html>");
    
            return stringBuilder.toString();
        }
    
        // 按照字符串拼装的方式, 生成 html
        public static String getArticleListPage(List<Article> articles, User user) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("<html>");
            stringBuilder.append("<head>");
            stringBuilder.append("<meta charset=\"utf-8\">");
            stringBuilder.append("<title>提示页面</title>");
            stringBuilder.append("<style>");
            // style 标签内部就是写 CSS 的逻辑
            stringBuilder.append(".article {" +
                    "color: #333;" +
                    "text-decoration: none;" +
    //                "display: inline-block;" +
                    "width: 200px;" +
                    "height: 50px;" +
                    "}");
            stringBuilder.append(".article:hover {" +
                    "color: white;" +
                    "background-color: orange;" +
                    "}");
            stringBuilder.append("body {" +
                    "background-repeat: none;" +
                    "background-position: 0 center;" +
                    "}");
            stringBuilder.append("</style>");
            stringBuilder.append("</head>");
            stringBuilder.append("<body>");
    
            stringBuilder.append("<h3> 欢迎您! " + user.getName() + "</h3>");
            stringBuilder.append("<hr>");
            // 要有一个文章列表. 显示每个文章的标题.
            for (Article article : articles) {
                stringBuilder.append(String.format("<div style=\"width: 200px; height: 50px; line-height: 50px\"> <a class=\"article\" href=\"article?articleId=%d\"> %s </a>" +
                                "<a href=\"deleteArticle?articleId=%d\"> 删除 </a></div>",
                        article.getArticleId(), article.getTitle(), article.getArticleId()));
            }
            stringBuilder.append("<hr>");
            stringBuilder.append(String.format("<div>当前共有博客 %d 篇</div>", articles.size()));
    
            // 在这里新增发布文章的区域
            stringBuilder.append("<div> 发布文章 </div>");
            stringBuilder.append("<div>");
            stringBuilder.append("<form method=\"post\" action=\"article\">");
            stringBuilder.append("<input type=\"text\" style=\"width: 500px; margin-bottom: 5px;\" name=\"title\" placeholder=\"请输入标题\">");
            stringBuilder.append("<br>");
            stringBuilder.append("<textarea name=\"content\" style=\"width: 500px; height: 300px;\"></textarea>");
            stringBuilder.append("<br>");
            stringBuilder.append("<input type=\"submit\" value=\"发布文章\">");
            stringBuilder.append("</form>");
            stringBuilder.append("</div>");
    
            stringBuilder.append("</body>");
            stringBuilder.append("</html>");
            return stringBuilder.toString();
        }
    
        public static String getArticleDetailPage(Article article, User user, User author) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("<html>");
            stringBuilder.append("<head>");
            stringBuilder.append("<meta charset=\"utf-8\">");
            stringBuilder.append("<title>提示页面</title>");
            stringBuilder.append("<style>");
            // style 标签内部就是写 CSS 的逻辑
            stringBuilder.append("a {" +
                    "color: #333;" +
                    "text-decoration: none;" +
                    "display: inline-block;" +
                    "width: 200px;" +
                    "height: 50px;" +
                    "}");
            stringBuilder.append("a:hover {" +
                    "color: white;" +
                    "background-color: orange;" +
                    "}");
            stringBuilder.append("body {" +
                    "background-repeat: none;" +
                    "background-position: 0 center;" +
                    "}");
            stringBuilder.append("</style>");
            stringBuilder.append("</head>");
            stringBuilder.append("<body>");
            stringBuilder.append("<h3> 欢迎您! " + user.getName() + "</h3>");
            stringBuilder.append("<hr>");
    
            stringBuilder.append(String.format("<h1>%s</h1>", article.getTitle()));
            stringBuilder.append(String.format("<h4>作者: %s</h4>", author.getName()));
            // 构造正文的地方.
            // HTML 中本来就不是用 \n 表示换行的.
            stringBuilder.append(String.format("<div>%s</div>", article.getContent()
                    .replace("\n", "<br>")));
    
            stringBuilder.append("</body>");
            stringBuilder.append("</html>");
            return stringBuilder.toString();
        }
    }
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值