文章目录
- 实现获取博客列表页功能
- 1. 约定前后端交互接口
- 2. 实现后端代码
- 3. 实现前端代码
- 4. 测试代码
- 5. 涉及到的两个 Bug
 
实现获取博客列表页功能
 
 
 当前的博客列表上的数据都是写死的,符合逻辑的做法是,通过数据库读取数据后显示到页面上。
此处就需要打通前后端交互的操作。
 让博客列表页在加载的时候,通过 Ajax 给服务器发一个请求,服务器查数据库获取到博客列表页数据,再返还给服务器,浏览器再根据数据构造页面的内容。
这样的交互过程也称为 前后端分离
 意思是前端只向后端请求数据,而不请求具体的页面,后端也仅仅是返回数据。
这样设计的目的就是为了前端和后端更加的解耦,由浏览器进行具体的页面渲染,
 减少了服务器的工作量。
1. 约定前后端交互接口
 
我们约定前端发起的 请求 是 GET,路径是 /blog
后端返回的 响应 使用的是 json 格式的数据来组织

 
 以上就是一个 json 格式的数组。
2. 实现后端代码
 此时创建一个新的 BlogServlet 类。
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.先查询数据库
        BlogDao blogDao = new BlogDao();
        // 使用 List 来表示
        List<Blog> blogs = blogDao.selectAll(); // 调用方法直接查询出全部的博客列表
        // 2.使用 ObjectMapper 将 blogs 转成符合要求的 json 格式的字符串
        String respJson = objectMapper.writeValueAsString(blogs);
        // 写回去
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(respJson);
    }
}
3. 实现前端代码
 按照以下步骤用 vscode 打开这个博客列表页的文件。
 
 
 
 在博客列表页加载过程中,触发 ajax ,访问服务器中的数据,再把拿到的数据构造到页面中。
 
 将原来博客列表页的文章摘抄只留下一篇作为一个样例,这个样例在代码写完的时候也可以删除。
 
 
 
 
 
 可以看到此时的博客就只有一篇了。
 
 
 (1) 引入 jQuery
 
 在前端代码下使用一个 script 标签,在这个标签里引入 jQuery。
 
 
 
 
 (2) 在页面加载的时候,向服务器发起请求,获取博客列表的数据
 <script>
     // 在页面加载的时候,向服务器发起请求,获取博客列表的数据
     function getBlogs() {
         $.ajax({
             type: 'get',
             url: 'blog',
             success: function(body) {
                 // 响应的正文是一个 json 格式的字符串,此时已经被 jQuery 自动解析成一个 js 的对象数组了
                 // 此时直接 for 循环遍历即可
                 for (let blog of body) {
                     // 按照之前的写好的 html 代码构造页面内容
                        
                 }
             }
         })
     }
     
     // 记得调用方法
     getBlogs();
 </script>
 上面的 type 和 url 分别是 get 和 blog ,这是因为这些都是在之前前后端交互接口中就约定好了。
 
 
 (3) 构造页面内容
这里所构造的页面内容要参考之前写好的 html 代码。
 
 
 
 根据上面的图片可以看到,有 5 个需要构造的内容。
 
 ① 构造整个博客
let blogDiv = document.createElement('div');
blogDiv.className = 'blog';
 因为整个博客是一个 div 标签,因此这里的 createElement 里是一个 div。
 而它的 类名 是 blog,因此这里的 clasName 为 blog。
 
 
 ② 构造标题
let titleDiv = document.createElement('div');
titleDiv.className = 'title';
// 把标题获取到并且设置进去
titleDiv.innerHTML = blog.title;
// 将构造好的标题添加进整个博客页面
blogDiv.appendChild(titleDiv);
 因为 标题 是一个 div 标签,因此这里的 createElement 里是一个 div。
 而它的 类名 是 title,因此这里的 clasName 为 title。
 
 
 ③ 构造发布时间
let dateDiv = document.createElement('div');
dateDiv.className = 'date';
dateDiv.innerHTML = blog.postTime;
blogDiv.appendChild(dateDiv);
 这里的代码和上面的含义是一致的,只不过在第三条语句中的 blog.postTime。
 因为在前后端交互接口中约定好了,发布时间是 postTime。
 
 
 
 
 ④ 构造博客摘要
let descDiv = document.createElement('div');
descDiv.className = 'desc';
descDiv.innerHTML = blog.content;
blogDiv.appendChild(descDiv);
 这里的 blog.content 是由于前后端交互接口约定好了。
 
 
 
 
 ⑤ 构造查看全文按钮
let button = document.createElement('a');
button.innerHTML = '查看全文 >>';
// 期望点击按钮后会跳转到博客详情页
// 为了让博客详情页知道点了哪篇博客,把 blogId传过去
button.href = 'blog.detail.html?blogId=' + blog.blogId;
blogDiv.appendChild(button);
 blog.detail.html 这是 博客详情页 的文件名,通过 blogId 来获取具体哪一篇博客。
 
 
 
 此时的 blogDiv 只是创建出来了,还没有把它放到下图圈出的 div 里面。
 
 
 
 
 此时需要先找到 父元素,上述图片中的 container-right 就是父元素。
首先在 for 循环的前面加上下面的代码。
 let containerRight = document.querySelector('.container-right');
 接着在 for 的里面加上下面的代码
 // 把 blogDiv 加到父元素中
 containerRight.appendChild(blogDiv);
 
 整体代码
<script>
    // 在页面加载的时候,向服务器发起请求,获取博客列表的数据
    function getBlogs() {
        $.ajax({
            type: 'get',
            url: 'blog',
            success: function(body) {
                // 响应的正文是一个 json 格式的字符串,此时已经被 jQuery 自动解析成一个 js 的对象数组了
                // 此时直接 for 循环遍历即可
                for (let blog of body) {
                    // 按照之前的写好的 html 代码构造页面内容
                    let containerRight = document.querySelector('.container-right');
                    // 构造整个博客
                    let blogDiv = document.createElement('div');
                    blogDiv.className = 'blog';
                    // 构造标题
                    let titleDiv = document.createElement('div');
                    titleDiv.className = 'title';
                    // 把标题获取到并且设置进去
                    titleDiv.innerHTML = blog.title;
                    // 将构造好的标题添加进整个博客页面中
                    blogDiv.appendChild(titleDiv);
                    
                    // 构造发布时间
                    let dateDiv = document.createElement('div');
                    dateDiv.className = 'date';
                    dateDiv.innerHTML = blog.postTime;
                    blogDiv.appendChild(dateDiv);
                    // 构造博客摘要
                    let descDiv = document.createElement('div');
                    descDiv.className = 'desc';
                    descDiv.innerHTML = blog.content;
                    blogDiv.appendChild(descDiv);
                    // 构造查看全文按钮
                    let button = document.createElement('a');
                    button.innerHTML = '查看全文 >>';
                    // 期望点击按钮后会跳转到博客详情页
                    // 为了让博客详情页知道点了哪篇博客,把 blogId传过去
                    button.href = 'blog.detail.html?blogId=' + blog.blogId;
                    blogDiv.appendChild(button);
                    // 把 blogDiv 加到父元素中
                    containerRight.appendChild(blogDiv);
                }
            }
        })
    }
    // 记得调用方法
    getBlogs();    
</script>
 此时 博客列表页 就实现完成了。
4. 测试代码
 首先要在数据库中插入测试数据。
 
 
 
 在地址栏中输入 http://127.0.0.1:8080/blog-system/blog.list.html。
blog.list.html 是博客列表页的文件名,blog-system 是项目名称。
 
 
 
 可以看到此时在数据库插入的数据就显示到了博客列表页中。
 
 此时点击 “查看全文” 按钮,就会自动跳转到 博客详情页。
 
 
 
 此时显示的就是博客详情页界面了。
 
 
 
 
 
 代码中实现的和跳转到博客详情页之后得地址栏是相同的。
5. 涉及到的两个 Bug
 1、时间戳
 
 
 
 可以看到此时显示的是一个时间戳,而不是一个格式化时间。
 
 
 2、顺序
 
 按照书写博客的逻辑,应该是先完成的博客在下面,后完成的在上面。
 但是此时的顺序是相反的
 
 
 
 根据上面在数据库中插入的结果可以看出,博客列表页展示出来的效果的顺序的确是不符合逻辑的。
 
 
 (1) 顺序问题的解决办法
 
 在 BlogDao 类(在封装数据库的操作中) 中找到 selectAll 方法,将这个方法中的 sql 语句更改为以下语句:
String sql = "select * from blog order by postTime desc";
 也就是在 blog 后面添加上 order by postTime desc。
 order by postTime 表示的是 按照发布时间排序,desc 表示的是 排的是 降序。
 
 
 (2) 时间戳问题的解决办法
 
 搜索 SimpleFormatter,查一下它的格式。
 
 
 
 接下来在 Blog 类中,添加上下面的这段代码。
 public String getPostTime() {
     // 把时间戳转成 格式化 时间
     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     return simpleDateFormat.format(postTime);
 }
 重启服务器后在地址栏输入路径。
 
 
 
 可以看到此时的发布时间和顺序就已经正确了,此时博客列表页就已经全部完成了。



















