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

Feign接口调用-请求响应数据底层实现

Feign 使用编解码器(Encoder/Decoder)处理请求和响应的序列化与反序列化。默认使用 Jackson 编解码器,支持 JSON 格式。


Jackson 是一个广泛使用的 JSON 编解码库,用于将 Java 对象序列化为 JSON 字符串(编码),以及将 JSON 字符串反序列化为 Java 对象(解码)。它的底层实现逻辑非常高效且灵活,以下是 Jackson 编解码器的底层实现逻辑详解:


1. Jackson 的核心组件

Jackson 的核心组件包括:

ObjectMapper:核心类,负责序列化和反序列化操作。

JsonParser:用于解析 JSON 数据流,生成令牌(tokens)。

JsonGenerator:用于生成 JSON 数据流。

Serializer:负责将 Java 对象转换为 JSON 数据。

Deserializer:负责将 JSON 数据转换为 Java 对象。

AnnotationIntrospector:用于解析注解(如 @JsonProperty、@JsonIgnore 等)。

2. Jackson 的编码(序列化)流程

编码是将 Java 对象转换为 JSON 字符串的过程。
2.1 调用 ObjectMapper.writeValueAsString()
用户调用 ObjectMapper.writeValueAsString(Object) 方法,传入需要序列化的 Java 对象。
2.2 选择序列化器
ObjectMapper 根据对象的类型,从 SerializerProvider 中获取对应的 JsonSerializer。

如果对象类型是简单类型(如 String、Integer),使用内置的序列化器。

如果对象类型是复杂类型(如 POJO),使用 BeanSerializer。
2.3 生成 JSON 数据
JsonSerializer 使用 JsonGenerator 生成 JSON 数据。

JsonGenerator 将 Java 对象的字段逐个写入 JSON 数据流。

对于字段名,使用 @JsonProperty 注解或字段名本身。

对于字段值,递归调用序列化器。
2.4 处理注解
如果字段上有注解(如 @JsonIgnore、@JsonProperty),
AnnotationIntrospector 会处理这些注解,
决定是否忽略字段或修改字段名。
2.5 返回 JSON 字符串
JsonGenerator 将生成的 JSON 数据写入字符串或输出流,
最终返回 JSON 字符串。

3. Jackson 的解码(反序列化)流程

解码是将 JSON 字符串转换为 Java 对象的过程。
3.1 调用 ObjectMapper.readValue()
用户调用 ObjectMapper.readValue(String, Class) 方法,
传入 JSON 字符串和目标 Java 类型。
3.2 创建 JsonParser
ObjectMapper 创建 JsonParser,用于解析 JSON 数据流。

JsonParser 将 JSON 字符串分解为一系列令牌(tokens),
如 START_OBJECT、FIELD_NAME、VALUE_STRING 等。
3.3 选择反序列化器
ObjectMapper 根据目标类型,从 DeserializerProvider 中获取对应的 JsonDeserializer。

如果目标类型是简单类型(如 String、Integer),使用内置的反序列化器。

如果目标类型是复杂类型(如 POJO),使用 BeanDeserializer。
3.4 解析 JSON 数据
JsonDeserializer 使用 JsonParser 逐个读取令牌,构建 Java 对象。

对于字段名,使用 @JsonProperty 注解或字段名本身。

对于字段值,递归调用反序列化器。
3.5 处理注解
如果字段上有注解(如 @JsonIgnore、@JsonProperty),
AnnotationIntrospector 会处理这些注解,决定是否忽略字段或修改字段名。
3.6 返回 Java 对象
JsonDeserializer 将解析后的数据填充到目标 Java 对象中,并返回该对象。

4. Jackson 的底层实现细节

4.1 ObjectMapper 的核心作用
ObjectMapper 是 Jackson 的核心类,负责管理序列化和反序列化的配置(如日期格式、空值处理等)。

它内部维护了 SerializerProvider 和 DeserializerProvider,用于获取序列化器和反序列化器。
4.2 JsonParser 的工作原理
JsonParser 使用基于事件驱动的模型解析 JSON 数据。

它将 JSON 字符串分解为一系列令牌(tokens),如:

START_OBJECT:表示 JSON 对象的开始({)。

FIELD_NAME:表示字段名。

VALUE_STRING:表示字符串值。

END_OBJECT:表示 JSON 对象的结束(})。
4.3 JsonGenerator 的工作原理
JsonGenerator 用于生成 JSON 数据流。

它提供了一系列方法(如 writeStartObject()、writeFieldName()、writeString())来构建 JSON 数据。
4.4 序列化器和反序列化器的注册
Jackson 支持自定义序列化器和反序列化器。

可以通过 SimpleModule 注册自定义的序列化器和反序列化器:
SimpleModule module = new SimpleModule();
module.addSerializer(User.class, new UserSerializer());
module.addDeserializer(User.class, new UserDeserializer());
objectMapper.registerModule(module);
4.5 注解处理
Jackson 支持丰富的注解,用于控制序列化和反序列化的行为。

常见的注解包括:

@JsonProperty:指定字段名。

@JsonIgnore:忽略字段。

@JsonFormat:指定日期格式。

@JsonInclude:控制空值的序列化行为。

5. Jackson 的性能优化

缓存:Jackson 缓存了序列化器和反序列化器,避免重复创建。

流式 API:JsonParser 和 JsonGenerator 使用流式 API,减少内存占用。

线程安全:ObjectMapper 是线程安全的,可以在多线程环境中共享。

6. 示例代码

6.1 序列化
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(1, "John");
String json = objectMapper.writeValueAsString(user);
System.out.println(json); // 输出: {"id":1,"name":"John"}
6.2 反序列化
String json = "{\"id\":1,\"name\":\"John\"}";
User user = objectMapper.readValue(json, User.class);
System.out.println(user.getName()); // 输出: John
6.3 自定义序列化器
public class UserSerializer extends StdSerializer<User> {
    protected UserSerializer() {
        super(User.class);
    }

    @Override
    public void serialize(User user, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        gen.writeNumberField("userId", user.getId());
        gen.writeStringField("userName", user.getName());
        gen.writeEndObject();
    }
}
6.4 自定义反序列化器
public class UserDeserializer extends StdDeserializer<User> {
    protected UserDeserializer() {
        super(User.class);
    }

    @Override
    public User deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        int id = node.get("userId").asInt();
        String name = node.get("userName").asText();
        return new User(id, name);
    }
}

7. 总结

Jackson 的编解码器底层实现逻辑包括:

序列化:通过 ObjectMapper 和 JsonGenerator 将 Java 对象转换为 JSON 字符串。

反序列化:通过 ObjectMapper 和 JsonParser 将 JSON 字符串转换为 Java 对象。

注解处理:通过 AnnotationIntrospector 解析注解,控制序列化和反序列化的行为。

性能优化:通过缓存、流式 API 和线程安全机制提高性能。

Jackson 的高效性和灵活性使其成为 Java 生态中最流行的 JSON 编解码库。

tips:
今天碰到一个问题,后端定义的响应体字段类型明明是Long类型,
结果响应却是String类型的;原因就是因为序列化时看到Long类型会转成String;

就类似上面4.4说的有自定义的处理:
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);//
module.addDeserializer(User.class, new UserDeserializer());
objectMapper.registerModule(module);


http://www.kler.cn/a/547131.html

相关文章:

  • Vue3实现优雅的前端版本更新提示
  • 布隆过滤器到底是什么东西?它有什么用
  • 【推荐】碰一碰发视频源码搭建,支持OEM
  • PyTorch 混合精度训练中的警告处理与代码适配指南
  • Vue 3 30天精进之旅:Day 24 - 国际化支持
  • CI/CD部署打包方法
  • Flask与Jinja2模板引擎:打造动态Web应用
  • Linux权限提升-内核溢出
  • 华象新闻 | 2月20日前谨慎升级 PostgreSQL 版本
  • 策略模式-小结
  • DeepSeek-R1私有化部署教程 | Linux服务器搭建AI大语言模型
  • 【Unity】 HTFramework框架(六十)Assistant助手(在Unity中接入DeepSeek等AI语言大模型)
  • 【ARM】JTAG接口介绍
  • 图的邻接表实现代解析【数据结构】
  • 深度整理总结MySQL——Expalin指南(二)
  • WEB安全--SQL注入--INTO OUTFILE
  • 03-微服务01(服务拆分、RestTemplate,nacos、OpenFeign、日志)
  • 软考-系统架构设计师(月更版)
  • 青少年编程与数学 02-009 Django 5 Web 编程 12课题、表单处理
  • 大载重无人机树木、竹子山林吊运技术详解