当前位置: 首页 > backend >正文

【博客系统】博客系统第二弹:实现博客列表接口

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


实现博客列表


约定前后端交互接口


  • [请求]

    /blog/getList GET
    
  • [响应]

    {"code": 200,"errMsg": null,"data": [{"id": 1,"title": "第一篇博客","content": "111我是博客正文我是博客正文我是博客正文","userId": 1,"updateTime": "2024-08-22 11:27:03"},.....]
    }
    

    客户端给服务器发送一个 /blog/getlist 这样的 HTTP 请求,服务器给客户端返回了一个 JSON 格式的数据。


实现服务器代码


SimpleDateFormat


@Data
public class BlogInfoResponse {private Integer id;private String title;private String content;private Integer userId;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime updateTime;
}

补充说明:

LocalDateLocalDataTime 都类似于时间工具类 Data,只是会分出时区,前者是具体的年月日,后者则是年月日时分秒

通过 @JsonFormat 设置页面返回的日期格式,格式参考 Overview (Java Platform SE 8 )。

image-20250427205224419


image-20250427205258242


SimpleDateFormat 可以搭配 Data 对象一起使用,可以按照我们配置的格式,输出当前时间,优化 Data 的可读性:

image-20250427210147705


Controller


@RequestMapping("/blog")
@RestController
public class BlogController {@Autowiredprivate BlogService blogService;@RequestMapping("/getList")public List<BlogInfoResponse> getList() {return blogService.getList();}
}

使用 SOA 架构改进 Service


Impl


基于 SOA 理念,Service 采用接口对外提供服务,实现类用 Impl 的后缀与接口区别

image-20250427105000826

SOA(Service-Oriented Architecture,面向服务的架构)是一种高层级的架构设计理念,可通过在网络中使用基于通用通信语言的服务接口,让软件组件可重复使用。

image-20250427110646930


image-20250427111414867


image-20250427112728937


接口测试:

image-20250427112910608


优化返回响应


在上面的测试中,我们发现给前端返回的信息有 deleteFlag,并且 createTimeupdateTime 只需要在页面上显示一个即可,所以我们还需要对后端返回响应再进一步处理:

image-20250427121300625


纠正:下图中的 BlogReponse 改为 BlogInfoReponse

image-20250427121454325


修改接口返回值 BlogService :

image-20250427170727343


修改 BlogService 中的部分代码,修改重写方法 getList() 的返回值;

image-20250427170851803


因为在 mapper 层,泛型已经锁定了 BlogInfo这个实体类:

image-20250427170957290


调用条件构造器, 并执行完对应 SQL 语句后,因为 Mapper 中 extends BaseMapper<BlogInfo>, List<BlogInfo> 不能修改:

image-20250427171151424


遍历集合对象方法 stream( ).map


BlogServiceImplgetList() 方法中,需将 Mapper 返回的 BlogInfo 类型的 List 转换为 BlogInfoResponse 类型的 List,再返回给 Controller ;可用 for 循环或 lambda 表达式实现:

image-20250427172113669


使用 lamda 表达式遍历 blogInfos 中的每一个元素,然后在 { } 中将 BlogInfo 类型转为BlogInfoResponse

image-20250427172442333


使用工具类 BeanUtils 内置方法拷贝源实体类属性值


我们可以使用 setter() 对 blogInfoReponse 的每个属性赋值,也可以使用 Spring 提供的工具类 BeanUtil,并且调用这个工具类的内置方法 copyProperties

image-20250427173053058


image-20250427173223706


使用collect(Collectors.toList( ))将遍历元素存入集合


又因为 getList() 方法的返回值为 List<BlogInfoReponse>,所以我们要把 lamda 表达式返回的每一个 blogInfoReponse 存入一个集合中:

image-20250427173557444


如上图,调用的是 collect(Collectors.toList()) 方法,将转换好的对象放入集合中,并接收,接收后将集合返回:

image-20250427173658650


image-20250427170620823


接口测试


重新测试接口:

image-20250427174147924


BlogInfoReponse 中加上 @Data 注解后,重新测试接口,此时前端拿到的响应,就没有 delete_flag updateTime 字段了:

image-20250427174236130

public interface BlogService {List<BlogInfoResponse> getList();
}
@Service
public class BlogServiceImpl implements BlogService {@Autowiredprivate BlogInfoMapper blogInfoMapper;@Overridepublic List<BlogInfoReponse> getList() {QueryWrapper<BlogInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lambda().eq(BlogInfo::getDeleteFlag, 0);List<BlogInfo> blogInfos = blogInfoMapper.selectList(queryWrapper);List<BlogInfoReponse> blogInfoReponses = blogInfos.stream().map(blogInfo -> {BlogInfoReponse blogInfoReponse = new BlogInfoReponse();BeanUtils.copyProperties(blogInfo, blogInfoReponse);return blogInfoReponse;}).collect(Collectors.toList());return blogInfoReponses;}
}

部署程序,验证服务器是否能正确返回数据,使用 URL http://127.0.0.1:8080/blog/getList 即可。


实现客户端代码


修改 blog_list.html,删除之前写死的博客内容(即 <div class="blog">),并新增 js 代码处理 ajax 请求。

  • 使用 ajax 给服务器发送 HTTP 请求。
  • 服务器返回的响应是一个 JSON 格式的数据,根据这个响应数据使用 DOM API 构造页面内容。
  • 跳转到博客详情页的 url 形如 blog_detail.html?blogId=1,这样就可以让博客详情页知道当前是要访问哪篇博客。
$.ajax({type: "get",url: "/blog/getlist",success: function (result) {if (result.code == 200 && result.data != null && result.data.length > 0) {// 循环拼接数据到 documentvar finalHtml = "";for (var blog of result.data) {finalHtml += '<div class="blog">';finalHtml += '<div class="title">' + blog.title + '</div>';finalHtml += '<div class="date">' + blog.createTime + '</div>';finalHtml += '<div class="desc">' + blog.content + '</div>';finalHtml += '<a class="detail" href="blog_detail.html?blogId=' + blog.id + '">查看全文&gt;&gt;</a>';finalHtml += '</div>';}$(".right").html(finalHtml);}}
});

通过 URL http://127.0.0.1:8080/blog_list.html 访问服务器,验证效果。

image-20250422195039798


在这里插入图片描述

在这里插入图片描述

http://www.xdnf.cn/news/2604.html

相关文章:

  • T检验、F检验及样本容量计算学习总结
  • 通过示例学习:连续 XOR
  • SpringBoot驾校报名小程序实现
  • 详细PostMan的安装和基本使用方法
  • 【SF】在 Android 显示系统中,图层合成方式 Device 和 Client 的区别
  • 文章记单词 | 第50篇(六级)
  • Zookeeper HA集群搭建
  • 昂瑞微蓝牙OM6621系列对比选型指南
  • 《代码整洁之道》第8章 边界 - 笔记
  • NCCL 通信与调试
  • Grok发布了Grok Studio 和 Workspaces两个强大的功能。该如何使用?如何使用Grok3 API?
  • 深度学习与SLAM特征提取融合:技术突破与应用前景
  • 深入解读:2025 数字化转型管理 参考架构
  • 视频HLS分片与关键帧优化深度解析
  • 2025 网络安全技术深水区探索:从 “攻防对抗” 到 “数字韧性” 的范式跃迁
  • VRRP与BFD在冗余设计中的核心区别:从“备用网关”到“毫秒级故障检测”
  • JavaScript中主动抛出错误的方法
  • 【java】lambda表达式总结
  • 类-python
  • AI中Token的理解与使用总结
  • seededit: Align image re-generation to image editing
  • 【中级软件设计师】编译和解释程序的翻译阶段、符号表 (附软考真题)
  • RC吸收电路参数设置实战
  • DJL FastText (FtModel) 使用指南
  • 如何编写企业的数据标准管理办法
  • 人大金仓sys_rman备份脚本
  • 【SAP-CO】标准价(S价)和移动平均价(V价)
  • 合理布局结构体,精打细算 cacheline
  • 设计并实现一个基于 Java + Spring Boot + MySQL 的通用多租户权限系统
  • 计算机网络-运输层(1)