苍穹外卖 - Day02 学习笔记

一、核心功能:新增员工

在实现新增员工功能时,有几个关键的技术点和设计考量需要我们掌握。

1.1 数据传输对象 (DTO) 的应用

核心概念: 数据传输对象(Data Transfer Object, DTO)是在应用程序不同分层之间传递数据的专用对象。其主要目的是封装数据,实现层与层之间的解耦,并精确控制数据传输的粒度,避免直接暴露领域模型(Entity/POJO)的完整结构。

(聊个通俗易懂的:)

把它想象成一个"定制快递盒"。前端发来的数据,或者后端要发给前端的数据,不一定和数据库里存的那个 Employee 对象一模一样。DTO 就是根据当前操作需要,量身定做的"盒子",只装必要的字段。这样各层之间传递数据就更清爽、安全。

实践要点:

  • 层间数据载体: Controller 通常用 DTO 接收前端数据,Service 层处理业务时也可能用到 DTO。

  • 业务逻辑补充: Service 层将 DTO 数据转换为实体对象存库前,需补充如创建时间、更新时间、操作人、默认状态,以及对密码进行加密处理等。

  • 属性拷贝: 可使用 BeanUtils.copyProperties(target, source) 简化 DTO 与实体对象间的属性复制。

1.2 JWT (JSON Web Token) 令牌认证的应用

核心概念: JSON Web Token (JWT) 是一种开放标准 (RFC 7519),用于在各方之间安全地传输JSON格式的声明信息(Claims),常用于用户身份验证和授权。

(简单来说:)

用户登录成功后,服务器发一个加密的"令牌"(JWT)给前端。前端之后每次请求需要权限的接口,都带上这个"令牌"。服务器拿到"令牌"验证一下真伪和有效期,就知道这个用户是谁、有没有权限了。全程服务器不需要保存登录状态,很适合分布式系统。

基本流程:

  1. 用户登录,服务器验证凭据。

  2. 验证成功后,服务器根据用户信息、密钥、过期时间生成JWT。

  3. JWT返回给前端存储。

  4. 前端后续请求通过HTTP请求头携带JWT。

  5. 服务器验证JWT的有效性以处理请求。

1.3 ThreadLocal:线程局部变量的应用

核心概念: ThreadLocal 为每个使用该变量的线程提供一个独立的变量副本,从而实现线程间的数据隔离。常用于在单次请求的处理链路中传递用户身份等上下文信息。

(打个比方:)

ThreadLocal 就像给每个服务员(线程)配了一个专属托盘。服务员A的托盘放A客人的东西,服务员B的放B客人的,互不干扰。在Web应用里,一个请求通常由一个线程处理到底,我们就可以在请求开始时把当前用户ID放到这个线程的"托盘"里,后续业务逻辑随时能取用,不用传来传去。

常用方法:

  • set(T value): 存值到当前线程的副本。

  • get(): 取当前线程副本中的值。

  • remove(): 极其重要! 请求处理完毕后必须调用,以清除当前线程副本中的值,防止线程复用时的数据污染。

二、核心功能:员工分页查询

2.1 PageHelper 分页插件的应用

核心概念: PageHelper 是 MyBatis 的一款物理分页插件,能自动为SQL语句追加分页逻辑,简化开发。

(简单来说:)

你不用再操心怎么写 LIMIT 这类分页SQL了。执行查询前,用 PageHelper.startPage(页码, 每页数量) "打个招呼",它就帮你搞定分页。

基本使用步骤:

  1. 引入依赖并配置插件。

  2. 在Service层调用Mapper查询前,执行 PageHelper.startPage(pageNum, pageSize);

  3. 紧接着的Mapper查询结果会自动分页,并可封装到 PageInfo 对象中获取分页详情。

2.2 Web层响应的日期时间格式化

问题背景: Java 8 的日期时间类型(如 LocalDateTime)默认序列化为JSON时,格式可能不符合前端要求。

方式一:使用 @JsonFormat 注解 (Jackson库)

  • 做法: 在Java Bean的日期时间属性上直接添加 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

  • 特点: 简单直接,但若多处使用则较繁琐,主要影响序列化。

方式二:自定义消息转换器实现全局日期时间格式化 (推荐)

通过配置Spring MVC的JSON处理机制,实现全局统一的日期时间格式。

核心步骤概览:

  1. 创建自定义 JacksonObjectMapper:

    继承 ObjectMapper,在构造方法中为 LocalDateTime、LocalDate、LocalTime 等类型注册使用指定格式的序列化器 (Serializer) 和反序列化器 (Deserializer)。

    • 关键代码示意 (JacksonObjectMapper.java 构造函数内):

      复制代码
      // ...
      SimpleModule simpleModule = new SimpleModule();
      String dateTimePattern = "yyyy-MM-dd HH:mm:ss"; // 定义你的目标格式
      
      // 为 LocalDateTime 配置序列化和反序列化
      simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateTimePattern)));
      simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(dateTimePattern)));
      
      // ... (类似地为 LocalDate 和 LocalTime 配置) ...
      
      this.registerModule(simpleModule);
      // ...
  2. 在 WebMvcConfiguration 中注册此转换器:

    重写 extendMessageConverters 方法,创建 MappingJackson2HttpMessageConverter,将自定义的 JacksonObjectMapper 实例设置给它,并将其添加到转换器列表首位。

    • 关键代码示意 (WebMvcConfiguration.java):

      复制代码
      @Override
      protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
          MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
          converter.setObjectMapper(new JacksonObjectMapper()); // 使用自定义的ObjectMapper
          converters.add(0, converter); // 优先使用
      }

(一句话概括背后逻辑:)

我们定制了一个懂得按特定格式处理日期时间的"JSON翻译官"(JacksonObjectMapper),然后告诉Spring MVC:"以后所有Java对象和JSON字符串互转的活儿,都让这个配置了新翻译官的'JSON快递员'(MappingJackson2HttpMessageConverter)优先干!" 这样,整个项目的日期时间格式就都听话了。

三、补充知识:JSON序列化与日期格式化

在咱们日常用 Spring MVC 开发Web应用,尤其是前后端分离的项目时,后端Java对象和前端需要的JSON字符串之间的转换几乎无处不在。这个转换过程,其实就是由"序列化"和"反序列化"以及它们背后的"功臣"------ObjectMapperHttpMessageConverter 来完成的。理解了它们,你就能明白为什么自定义日期格式那套操作能起作用了。

3.1 序列化 (Serialization) 与 反序列化 (Deserialization)

  • 核心定义:

    • 序列化: 将程序内部的Java对象转换为一种可存储或可传输的通用格式(如JSON字符串)。

    • 反序列化: 将通用数据格式(如JSON字符串)转换回程序内部可用的Java对象。

(通俗点说:)

  • 序列化就好比把一个苹果(Java对象)榨成标准瓶装的苹果汁(JSON字符串)。

  • 反序列化就是朋友拿到这瓶苹果汁(JSON字符串)后,用某种方法把它变回一个能直接吃的苹果(Java对象)。

3.2 对象映射器 (ObjectMapper) - Jackson库的核心

  • 核心定义: ObjectMapper 是Jackson库的核心类,负责执行Java对象与JSON之间的实际转换工作。

(通俗点说:)

ObjectMapper 就是那个"榨汁机"兼"苹果还原机"。我们可以对这个机器进行各种精细调整(配置),比如告诉它日期这个"成分"要怎么处理。

3.3 HTTP消息转换器 (HttpMessageConverter) - Spring MVC的桥梁

  • 核心定义: 在Spring MVC框架中,HttpMessageConverter 负责读取HTTP请求体并将其转换为Java对象,或将Java对象转换为HTTP响应体。

(通俗点说:)

Controller 和前端之间传递数据(比如JSON),HttpMessageConverter 就是中间的"快递员"。MappingJackson2HttpMessageConverter 是专门负责JSON这种"快递"的"快递员",它打包拆包时,用的工具就是 ObjectMapper。

3.4 它们如何协同工作实现全局日期格式化?

  • 我们通过自定义 JacksonObjectMapper (规定好日期格式),然后创建一个新的 MappingJackson2HttpMessageConverter 并把自定义的 ObjectMapper 交给它,最后把这个"特配版"的转换器放到Spring MVC的转换器列表最前面。

  • 这样,当Spring MVC需要处理JSON时,会优先找到我们这个"特配版"转换器,它就会用我们定制的日期格式规则来工作。

相关推荐
小毛驴85013 分钟前
Linux 后台启动java jar 程序 nohup java -jar
java·linux·jar
DKPT1 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
好奇的菜鸟2 小时前
如何在IntelliJ IDEA中设置数据库连接全局共享
java·数据库·intellij-idea
巴伦是只猫3 小时前
【机器学习笔记Ⅰ】13 正则化代价函数
人工智能·笔记·机器学习
DuelCode3 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
优创学社23 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
好好研究3 小时前
学习栈和队列的插入和删除操作
数据结构·学习
幽络源小助理3 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
猴哥源码3 小时前
基于Java+springboot 的车险理赔信息管理系统
java·spring boot
YuTaoShao4 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展