页面展示效果
备注:这里我就截几张图片展示一些内容,由于页面之间的相互配合是一个动态的过程,所以说,很难演示逻辑。
1. 博客列表页
2. 博客内容页
3. 博客登录页
4. 博客编辑页
总代码
总结页面之间的交互逻辑
1. 博客列表页
2. 博客内容页
3. 博客登录页
判定用户有没有登录
注销操作
显示用户/作者信息
4. 博客编辑页
删除博客
谈一谈我的感受
当前的博客系统,我写了两个版本,先是写的【基于模板引擎】,后写的【基于前后端分离】,虽然现在的【基于前后端分离】更加流行,但是有好有坏。
在写【基于模板引擎】的时候,只需要把模板文件做好,后面在服务器端按照固定写法进行替换变量即可,所以,我认为,当前的项目,是【基于模板引擎】更加的简单,因为前端代码少,后端代码多。
在写【基于前后端分离】版本的时候,主要接触的前端还是太少,总是被 JS 代码绊住脚,但相对来说,这里的后端代码就更少了。
然而,不论哪个版本,它都是一种实现 Web 开发的一种方式。
所以我认为,
最核心的是:前后端交互的逻辑以及 HTTP 协议。
最难的是:两者以什么样的方式来进行交互,我们需要根据一种【事先约定】来设计好整个流程框架。
如果没有事先约定好一个【协议】,那么,如果在编程的过程中,一个地方出错了,那么整个设计全部崩盘。这种出错的地方包括:临时添加一个功能、临时除去一个功能、跳转接口出错了等等…
令我最深的印象就是:有一次,我在写后端代码的时候,发现没有按照 HTML 页面的标签顺序来写逻辑,这就导致了,后来在展示的时候,浏览器控制台爆出来很多很多的红色报错…
此外,在这个小小的项目中,我更加体会到了 Java 面向对象编程的思想,不管与前端交互,还是与数据之间的连接,都需要用 Java 对象作为中间桥梁。所有的变量,引用等等…都应该赋给一个对象的属性,而后,下次需要的时候,从 Java 对象中取。
而在前端呢,我认为最重要的是,刚开始设计的 HTML 页面,要把整个版心的内容想清楚了,才能够下手进行构造。
而数据库呢,我认为最重要的是,SQL 语句,不管使用什么样连接服务器的方式,最重要的,你得能够直接对数据库生效才行。
此外,当前项目中,也让我更加体会到了测试的关键,利用 Fiddler 抓包,可以很清楚地看到 HTTP 协议的信息。
此外,出现了问题,能不能快速地找到问题,前端或是后端,哪里出错了,这都需要很敏锐地做出判断,令我一个深刻的印象就是:在基于前后端分离版本的【删除博客】功能中,我代码写的很快,但是调试了一个多小时,最后才发现,是后端的重定向错误。
不管怎样,这个小项目还是花了我很长时间的,两个版本各做了两次,我认为,只有动手实践了,才能够真正掌握整个 Web 开发的流程。
补充功能
博客注册页
博客注册页是我后来想起来的一个功能,我心想,既然用户能登录,但不能注册,未免太不合理了,所以我就临时加上了这个页面。
(1) 作用:博客注册页是用于实现用户注册的页面,它不直接出现在用户面前,而是通过点击登录页面的【注册账号】这个链接,来进行跳转。
(2) 约定 POST 请求 的路径:" /BlogRegister "
客户端通过 form 表单来给服务器发送请求。
(3) 针对前端代码:通过 form 表单进行 HTTP 请求的提交,在提交的过程中,需要带上 【username】 、【password1】、【password2】这三个参数,以便于服务器端进行验证。
(4) 针对服务器端代码:创建一个 BlogRegisterServlet 来实现 HTTP 响应,登录成功后,预期跳转到博客登录页。
在前后端交互的过程中,我们要注意很多事项。例如:
注册的用户名与数据库中的用户名不能重合;重复输入一次密码,以此保障注册的密码不会失败;注册完成后,页面不能呆在原地,而是要进行跳转登录页。
而以上的这些问题,基本上都是要通过服务器端使用 if 语句进行控制,既要理解面向对象的思想,又要想清楚服务器如何与数据库进行交互。
前端代码和之前的博客登录页是一样的思想,我就不展示了,主要展示一下后端的代码:
@WebServlet("/BlogRegister") public class BlogRegisterServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html; charset=UTF-8"); // 从 HTTP 请求中获取 name 参数 String username = req.getParameter("username"); String password1 = req.getParameter("password1"); String password2 = req.getParameter("password2"); if (username == null || username.equals("")) { resp.getWriter().write("<h3> 您未输入用户名 </h3>"); return; } if (password1 == null || password1.equals("")) { resp.getWriter().write("<h3> 您未输入密码 </h3>"); return; } if (password2 == null || password2.equals("")) { resp.getWriter().write("<h3> 您未再次输入密码 </h3>"); return; } // 判断第二次密码是否输入正确 if (!password1.equals(password2)) { resp.getWriter().write("<h3> 您两次输入的密码不一致,请返回,并重新输入 </h3>"); return; } // 判断数据库中,是否有重名的用户 // 若用户名重名,那么就返回 UserDB userDB = new UserDB(); User user = userDB.searchByUsername(username); // 这里 if 语句中不应该使用 ( user.getUsername() != null ) // 因为这 user 这个对象本身就不为空 ( 有 userID 的存在 ) // 由于 MySQL 数据库中的 userID 是自增主键,那么必然是从 1 开始的 // 如果 userID 为 0,说明数据库中没有重复的用户了 if (user.getUserID() != 0) { resp.getWriter().write("<h3> 非常抱歉,你注册的用户名已经被其他用户使用,请换一个试试吧~ </h3>"); return; } // 代码走到这里,说明一切都符合条件 // 开始往数据库中插入数据 User newUser = new User(); newUser.setUsername(username); newUser.setPassword(password1); userDB.insert(newUser); // 一切都完成后,重定向至 登录页面 resp.sendRedirect("blog_login.html"); } }
展示效果
再次总结
这次临时添加页面,也给我带来了感触。如果在原有项目进行添加页面,可能并不仅仅就是 " 添加一个页面 " 这个事,因为它涉及到,对于之前页面的改动。这就好像:牵一发动全身一样。
这次添加新页面,我独立完成了 HTML、CSS、后端的这些代码,虽然整体框架不变,但改动的地方依然很多。总之,不管如何修改,都要遵循前后端的交互规律,也要考虑到数据库与服务器端的连接问题。
近两天,我完成了 Linux 的学习,下一篇博客就会详细介绍 Linux 和 Web 部署,我准备将此项目放到公网上,这样就算得上是一个真正的《网站》了。由于当前博客写的是基于 " 127.0.0.1 " 这样的环回 IP,所以说,也就只能自己进行本机的练习,学习了 Web 部署之后,就可以进行将项目公开到公网上,供用户使用了。