尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Retrofit Gson Converter 完全指南:JSON 序列化与反序列化的配置、原理与实战
Retrofit Gson Converter 完全指南JSON 序列化与反序列化的配置、原理与实战【免费下载链接】retrofitA type-safe HTTP client for Android and the JVM项目地址: https://gitcode.com/gh_mirrors/re/retrofit导读retrofit-converters/gson是 Retrofit 官方提供的 JSON 转换器模块它基于 Google 的 Gson 库让 Retrofit 接口方法可以自动完成Java 对象 → JSON 请求体与JSON 响应体 → Java 对象的双向转换。阅读完本文你将掌握 converter-gson 的依赖引入、默认与自定义Gson实例的两种创建方式、withStreaming()流式序列化开关以及底层TypeAdapter的调用机制与响应体完整消费检查等关键细节并了解如何将它与其它 Converter 混合使用而不冲突。一、模块定位Gson 与 Retrofit 之间的桥在 Retrofit 中Converter负责把方法的返回值类型如CallT中的T与 HTTP 报文进行互相转换。converter-gson提供的就是一个基于 Gson 的Converter.Factory实现正如模块自述见 retrofit-converters/gson/README.mdAConverterwhich uses Gson for serialization to and from JSON.它位于源码包的retrofit2.converter.gson之下核心类只有五个文件作用GsonConverterFactory.javaConverter 工厂入口对外提供create()/create(Gson)/withStreaming()GsonRequestBodyConverter.java请求体转换对象 →okhttp3.RequestBodyGsonResponseBodyConverter.java响应体转换okhttp3.ResponseBody→ 对象GsonStreamingRequestBody.java流式请求体封装供withStreaming()使用package-info.java包级注解声明模块描述使用 Gson 进行序列化定义于 retrofit-converters/gson/gradle.propertiesA Retrofit Converter which uses Gson for serialization。二、依赖引入Maven 与 Gradle 两种方式README 给出了标准坐标Group 为com.squareup.retrofit2Artifact 为converter-gsonMavenREADMEdependency groupIdcom.squareup.retrofit2/groupId artifactIdconverter-gson/artifactId versionlatest.version/version /dependencyGradleimplementation com.squareup.retrofit2:converter-gson:latest.version两点补充说明版本号README 中的latest.version是占位符实际应以你使用的 Retrofit 版本为准BOM 用户可直接从 retrofit-bom 统一管理版本。本仓库当前使用的 Gson 依赖版本为2.13.2声明于 gradle/libs.versions.tomlgson { module com.google.code.gson:gson, version 2.13.2 }。开发版快照README 说明开发版本的快照可以从 Sonatype 的snapshots仓库获取。若你需要体验未发布的特性可配置该快照仓库生产环境建议使用正式发布版本。三、基本用法一行代码接入 Retrofit官方 README 强调该 Converter 有两种使用形态自动创建默认Gson实例自行配置Gson实例后传入工厂从而进一步控制序列化行为。对应到 GsonConverterFactory.java 的两个静态工厂方法// 方式一使用默认 Gson 实例 GsonConverterFactory.create() // 方式二使用自定义配置的 Gson 实例 GsonConverterFactory.create(gson)在仓库的示例程序 samples/src/main/java/com/example/retrofit/SimpleService.java 中可以看到最典型的接入方式Retrofit retrofit new Retrofit.Builder() .baseUrl(https://api.example.com/) .addConverterFactory(GsonConverterFactory.create()) .build();之后接口方法的Body参数会被序列化为 JSON 请求体返回值泛型T则从 JSON 响应体反序列化而来interface GitHubService { POST(users/new) CallUser createUser(Body User user); // User → JSON 请求体 GET(users/{login}) CallUser getUser(Path(login) String login); // JSON 响应体 → User }传 null 的防御create(Gson gson)内部对空值做了显式校验见 GsonConverterFactory.javaif (gson null) throw new NullPointerException(gson null);因此传入null会立即抛出NullPointerException避免把问题延迟到请求执行阶段。四、源码原理Converter 是如何接入 Retrofit 的GsonConverterFactory继承自Converter.Factory重写了两个钩子方法见 GsonConverterFactory.javaOverride public ConverterResponseBody, ? responseBodyConverter( Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter? adapter gson.getAdapter(TypeToken.get(type)); return new GsonResponseBodyConverter(gson, adapter); } Override public Converter?, RequestBody requestBodyConverter( Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter? adapter gson.getAdapter(TypeToken.get(type)); return new GsonRequestBodyConverter(gson, adapter, streaming); }关键点在于gson.getAdapter(TypeToken.get(type))Type来自 Retrofit 在解析接口方法时收集的泛型信息如CallUser中的User或CallListRepo中的ListRepoTypeToken是 Gson 用于捕获泛型类型的手段保证ListRepo这类带泛型的类型也能拿到正确的TypeAdapter拿到TypeAdapter后请求与响应两个方向分别交给GsonRequestBodyConverter/GsonResponseBodyConverter执行。Retrofit 会在构建时遍历通过addConverterFactory注册的所有工厂找到第一个能返回非 null Converter 的工厂。这也是下文混合使用一节要特别注意顺序的原因。五、请求体序列化编码、Content-Type 与流式开关GsonRequestBodyConverter.java 实现了ConverterT, RequestBodystatic final MediaType MEDIA_TYPE MediaType.get(application/json; charsetUTF-8);这是本模块默认且唯一的 Content-Type意味着序列化固定采用UTF-8编码对应 Javadoc 中 Encoding to JSON ... will use UTF-8 的说明请求头Content-Type: application/json; charsetUTF-8这一点由单元测试 GsonConverterFactoryTest.java 直接断言验证。默认非流式路径的序列化过程是Buffer buffer new Buffer(); writeJson(buffer, gson, adapter, value); return RequestBody.create(MEDIA_TYPE, buffer.readByteString());即先把对象完整写入内存Buffer再一次性构造RequestBody。而writeJson静态方法揭示了底层真正的写法GsonRequestBodyConverter.javaWriter writer new OutputStreamWriter(sink.outputStream(), UTF_8); JsonWriter jsonWriter gson.newJsonWriter(writer); adapter.write(jsonWriter, value); jsonWriter.close();它通过gson.newJsonWriter()创建JsonWriter再委托TypeAdapter.write()完成字段级输出——因此你对Gson做的任何自定义如字段命名策略、空值策略、自定义TypeAdapter都会在请求序列化时生效。withStreaming()把序列化移到 HTTP 线程GsonConverterFactory.java 提供了流式变体public GsonConverterFactory withStreaming() { return new GsonConverterFactory(gson, true); }开启后requestBodyConverter返回的 GsonStreamingRequestBody.java 会直接在writeTo(BufferedSink)中调用writeJson把 JSON 字节写到网络流而不是先缓存到内存。其 Javadoc 说明了执行线程语义对Call.execute()序列化发生在调用线程对Call.enqueue()序列化发生在OkHttp 的后台线程响应反序列化则始终在 OkHttp 的后台线程进行。适用场景上传体积很大的请求体时流式写入可以避免整份 JSON 在内存中驻留。测试 GsonConverterFactoryTest.java 用序列化过程中抛异常的ErroringValue验证了流式行为若流式失效enqueue会同步抛出异常流式正常时异常经onFailure异步回调且错误类型/消息原样透传EOFException: oops!。六、响应反序列化严格消费整个 JSON 文档GsonResponseBodyConverter.java 实现了ConverterResponseBody, TJsonReader jsonReader gson.newJsonReader(value.charStream()); try { T result adapter.read(jsonReader); if (jsonReader.peek() ! JsonToken.END_DOCUMENT) { throw new JsonIOException(JSON document was not fully consumed.); } return result; } finally { value.close(); }这段实现有三个值得注意的设计按响应声明的字符集解码value.charStream()会依据响应头声明的 charset 创建字符流README 与 Javadoc 中when no charset is specified by a header, UTF-8即指此行为——没有显式 charset 时 OkHttp 默认按 UTF-8 解码。强制完整消费反序列化完成后会检查peek()是否已到达END_DOCUMENT若响应体还有未被消费的内容则抛出JsonIOException(JSON document was not fully consumed.)。这是防止静默忽略多余数据的严格性设计测试 GsonConverterFactoryTest.java 专门覆盖了该异常路径。及时关闭响应体无论成功还是抛异常finally中都会关闭ResponseBody避免连接泄漏。七、自定义 Gson 的完整实战README 明确指出one can be configured and passed to theGsonConverterFactoryto further control the serialization。以仓库测试 GsonConverterFactoryTest.java 为蓝本一个完整的自定义接入如下Gson gson new GsonBuilder() .registerTypeAdapter(AnInterface.class, new AnInterfaceAdapter()) .registerTypeAdapter(ErroringValue.class, ErroringValue.BROKEN_ADAPTER) .setLenient() .create(); GsonConverterFactory factory GsonConverterFactory.create(gson); // 可选切换为流式序列化 factory factory.withStreaming(); Retrofit retrofit new Retrofit.Builder() .baseUrl(server.url(/)) .addConverterFactory(factory) .build();测试中通过registerTypeAdapter为接口类型AnInterface注册了自定义TypeAdapterGsonConverterFactoryTest.java手动控制 JSON 键名与对象字段的映射。几个测试断言点值得借鉴序列化遵守 Gson 配置serializeUsesConfiguration验证当对象字段为null时输出为{}说明 Gson 的空值策略默认不序列化 null在请求方向生效GsonConverterFactoryTest.java反序列化同样遵守配置deserializeUsesConfiguration验证启用setLenient()后响应体{/* a comment! */}这类带注释的宽松 JSON 也能被解析GsonConverterFactoryTest.javaContent-Type 恒定两个方向均断言请求头为application/json; charsetUTF-8。仓库示例 samples/src/main/java/com/example/retrofit/AnnotatedConverters.java 也展示了GsonConverterFactory.create(gson)配合自定义Gson的写法。八、与其它 Converter 混合使用的顺序规则Gson对类型的支持极为灵活因此GsonConverterFactory的 Javadoc 给出了一条关键约定见 GsonConverterFactory.javaBecause Gson is so flexible in the types it supports, this converter assumes that it can handle all types. If you are mixing JSON serialization with something else (such as protocol buffers), you must add this instancelastto allow the other converters a chance to see their types.翻译成实践规则当你把 Gson Converter 与协议缓冲protobuf、XML 等其它 Converter 混用时GsonConverterFactory必须最后注册。因为 Retrofit 按注册顺序询问每个工厂Gson 工厂对几乎所有类型都来者不拒如果把它放在前面其它格式的类型就永远轮不到对应的工厂处理。仓库示例 samples/src/main/java/com/example/retrofit/JsonAndXmlConverters.java 中JSON 与 XML 两个 Converter 的注册顺序正是这一规则的直接体现.addConverterFactory(GsonConverterFactory.create(), SimpleXmlConverterFactory.create())九、本文关键结论速览主题结论依据依赖坐标com.squareup.retrofit2:converter-gsonREADME两种创建方式create()用默认 Gsoncreate(Gson)用自定义 GsonGsonConverterFactory.javaContent-Type 与编码固定application/json; charsetUTF-8请求方向固定 UTF-8GsonRequestBodyConverter.java响应字符集优先响应头声明的 charset未声明时默认 UTF-8GsonResponseBodyConverter.java严格性响应 JSON 未完整消费时抛JsonIOExceptionGsonResponseBodyConverter.java流式序列化withStreaming()将序列化移至调用线程/OkHttp 后台线程GsonConverterFactory.java混合使用顺序与其它 Converter 混用时Gson 工厂必须最后注册GsonConverterFactory.java底层机制通过gson.getAdapter(TypeToken.get(type))获取TypeAdapter完成双向转换GsonConverterFactory.java如果你需要对比或替换 JSON 方案仓库中还提供了基于其它库的同类模块例如 retrofit-converters/moshi、retrofit-converters/jackson若想进一步了解 Retrofit 在构建时如何遍历工厂解析 Converter可阅读核心类 retrofit/src/main/java/retrofit2/Retrofit.java 中的nextResponseBodyConverter/nextRequestBobyConverter相关实现。【免费下载链接】retrofitA type-safe HTTP client for Android and the JVM项目地址: https://gitcode.com/gh_mirrors/re/retrofit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Godot-demo-projects 指南:3 分钟跑通 40+ 官方可运行示例

Godot-demo-projects 指南:3 分钟跑通 40+ 官方可运行示例

Godot-demo-projects 指南:3 分钟跑通 40 官方可运行示例 【免费下载链接】godot-demo-projects Demonstration and Template Projects 项目地址: https://gitcode.com/GitHub_Trending/go/godot-demo-projects Godot-demo-projects 是 Godot Engine 官方提供…

📅 2026/9/18 22:51:37
Zcash 4.0.0 深度解析:Canopy 主网升级、Zcash 开发基金与 Rust tracing 日志系统

Zcash 4.0.0 深度解析:Canopy 主网升级、Zcash 开发基金与 Rust tracing 日志系统

Zcash 4.0.0 深度解析:Canopy 主网升级、Zcash 开发基金与 Rust tracing 日志系统 【免费下载链接】zcash Zcash - Internet Money 项目地址: https://gitcode.com/GitHub_Trending/zc/zcash Zcash 4.0.0 是承接 3.1.0 的里程碑版本,核心使命是在…

📅 2026/9/18 22:51:37
CANN 模型推理优化编排中的 Plan Dashboard 模板:从候选发现到最终验收的单一真相源实践

CANN 模型推理优化编排中的 Plan Dashboard 模板:从候选发现到最终验收的单一真相源实践

CANN 模型推理优化编排中的 Plan Dashboard 模板:从候选发现到最终验收的单一真相源实践 【免费下载链接】cann-recipes-infer 本项目针对LLM与多模态模型推理业务中的典型模型、加速算法,提供基于CANN平台的优化样例 项目地址: https://gitcode.com/c…

📅 2026/9/18 22:51:37
MORE NEWS

更多资讯

📰

ESP32 MCP C SDK 测试应用全解析:91 个用例覆盖 API、协议合规与内存安全

ESP32 MCP C SDK 测试应用全解析:91 个用例覆盖 API、协议合规与内存安全 【免费下载链接】esp-iot-solution Espressif IoT Library. IoT Device Drivers, Documentations and Solutions. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution …

📰

水稻叶病虫害分类实战:YOLO11cls数据集训练与部署指南

简介:面向水稻叶病虫害图像分类项目,这份资源提供真实场景下的高质量叶片图片数据及配套训练示例。数据集包含细菌性叶枯病、褐斑病、健康叶片、叶瘟病、叶鞘腐病、窄褐斑病、穗颈瘟、稻飞虱、纹枯病、钨黄病毒病共10个类别,约5000张图片&…

📰

Agent-SRE Helm Chart 实战指南:在 Kubernetes 上部署 AI 代理可靠性引擎与 AgentRollout 渐进式发布

Agent-SRE Helm Chart 实战指南:在 Kubernetes 上部署 AI 代理可靠性引擎与 AgentRollout 渐进式发布 【免费下载链接】agent-governance-toolkit AI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability…

📰

BERT文本分类在经济研究中的应用:论文复现全流程实战

先说明一下,我这边没有找到金星晔等(2024)《经济研究》这篇论文的原文全文,但你给的标题信息已经足够定位到这是哪一类工作:用BERT这类预训练语言模型做经济学文本分类,而且作者团队把整个流程(…

📰

PicoClaw vs OpenClaw 轻量助手对比,OpenClaw 的 Base URL 填 TaoToken 的 API 地址

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

postgres_lsp 安全规则 renamingTable 详解:拦截表重命名风险,守护迁移与线上查询

postgres_lsp 安全规则 renamingTable 详解:拦截表重命名风险,守护迁移与线上查询 【免费下载链接】postgres_lsp A Language Server for Postgres 项目地址: https://gitcode.com/GitHub_Trending/po/postgres_lsp 本指南以 postgres_lsp 项目中…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬