ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

swagger-codegen 生成的 Java 只读模型文档解读:以 okhttp-gson-parcelableModel 的 HasOnlyReadOnly 为例

swagger-codegen 生成的 Java 只读模型文档解读:以 okhttp-gson-parcelableModel 的 HasOnlyReadOnly 为例 开发工具代码生成API设计【免费下载链接】swagger-codegenswagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.项目地址https://gitcode.com/gh_mirrors/sw/swagger-codegen点击查看免费下载本文以 swagger-codegen 为 Java 客户端生成的模型文档HasOnlyReadOnly.md为线索逐层拆解自动生成模型文档的阅读方式、对应 Java 源码的落地形态以及背后readOnly只读属性机制在代码生成器中的实现原理。读完本文你将能够准确阅读任意一个由 swagger-codegen 生成的模型文档页面理解只读属性不生成 setter全只读模型等行为从 OpenAPI 定义到 Java 类代码的完整链路并能在自己的生成工程中快速定位与验证这些约定。一、模型文档是什么一份由生成器产出的数据契约说明在 swagger-codegen 生成的每个客户端工程中docs/目录下会为 OpenAPI/Swagger 定义中的每一个模型schema生成一份独立的 Markdown 文档。本文的主角是samples/client/petstore/java/okhttp-gson-parcelableModel/docs/HasOnlyReadOnly.md它对应的模型名为HasOnlyReadOnly全文结构极其精简但信息完整是典型的属性契约表式文档原文如下NameTypeDescriptionNotesbarString[optional]fooString[optional]这份表格是理解整个模型的核心骨架其四列含义分别为Name属性字段名对应 Java 源码中SerializedName注解里的值也是 JSON 序列化/反序列化时使用的键名Type属性类型。此模型两个属性均为StringDescription属性语义描述由 OpenAPI 定义中description字段透传而来本例未填写Notes属性约束标注。此处两条均为[optional]表示该属性不是必填未出现在定义模型的required列表中反之为[required]。此外模型名HasOnlyReadOnly本身就是生成器用来做回归测试的一类特殊模型——它暗示该模型的所有属性都是只读的readOnly。这一点需要结合生成的源码和生成器内部逻辑才能完全理解下文逐一展开。二、源码落地形态一份只有 getter、没有 setter 的 Parcelable 模型类与文档配套的生成源码位于samples/client/petstore/java/okhttp-gson-parcelableModel/src/main/java/io/swagger/client/model/HasOnlyReadOnly.java类声明为public class HasOnlyReadOnly implements Parcelable整体由几部分拼装而成。1. 字段声明与 JSON 注解SerializedName(bar) private String bar null; SerializedName(foo) private String foo null;每个属性对应一个private字段并通过 Gson 的SerializedName将 Java 字段名与 JSON 键名绑定。这正是okhttp-gson系列生成器使用 Gson 作为序列化层的体现。2. 只读属性的关键特征只有 getter没有 setterApiModelProperty(value ) public String getBar() { return bar; } ApiModelProperty(value ) public String getFoo() { return foo; }从源码结构可以明显看到该类只生成了getBar()/getFoo()两个读取方法而没有生成setBar()/setFoo()。这是 swagger-codegen 对readOnly: true属性的标准处理——只读属性在服务端由系统生成/返回客户端不应向其写入因此生成器刻意省略 setter从 API 层面杜绝反序列化后修改只读字段的误用。这也印证了模型名 HasOnlyReadOnly 的含义该模型的两个属性bar、foo均为只读属性于是整个模型变成了只有只读属性的模型——在生成器内部对应hasOnlyReadOnly标志。3. Parcelable 实现Android 生态的序列化支持okhttp-gson-parcelableModel与普通okhttp-gson生成器的最大区别在于额外实现了 Android 的Parcelable接口便于模型对象在 Android 的 Activity/Service/Binder 之间传递public void writeToParcel(Parcel out, int flags) { out.writeValue(bar); out.writeValue(foo); } HasOnlyReadOnly(Parcel in) { bar (String)in.readValue(null); foo (String)in.readValue(null); } public static final Parcelable.CreatorHasOnlyReadOnly CREATOR new Parcelable.CreatorHasOnlyReadOnly() { public HasOnlyReadOnly createFromParcel(Parcel in) { return new HasOnlyReadOnly(in); } public HasOnlyReadOnly[] newArray(int size) { return new HasOnlyReadOnly[size]; } };其中writeToParcel按字段顺序写出私有的Parcel in构造器按相同顺序读回CREATOR则负责在Intent传递后重建对象。这就是文档表格之外的隐含契约虽然文档只写了两个String属性但生成的模型还天然具备equals/hashCode/toString以及 Parcelable 序列化能力属于所有生成模型的通用底座。三、底层原理hasOnlyReadOnly与readOnlyVars在生成器中的实现文档页和 Java 类都是模板引擎的产物。要理解只读模型的判定与分流需要看生成器核心的两个类。1. 模型元数据结构CodegenModelmodules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenModel.java 定义了生成模型在内存中的统一表示其中与只读相关的字段public ListCodegenProperty readOnlyVars new ArrayListCodegenProperty(); // a list of read-only properties public ListCodegenProperty readWriteVars new ArrayListCodegenProperty(); // a list of properties for read, write ... public boolean hasOnlyReadOnly true; // true if all properties are read-only注意hasOnlyReadOnly的初始值为true这并非巧合而是一个先假设全只读、再被逐一否定的判定策略。2. 属性遍历与标记位翻转DefaultCodegenmodules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java 在把 OpenAPI 定义的每个属性转换为CodegenProperty时执行了三个关键步骤// set models hasOnlyReadOnly to false if the property is read-only if (!Boolean.TRUE.equals(cp.isReadOnly)) { m.hasOnlyReadOnly false; } ... // if required, add to the list requiredVars if (Boolean.TRUE.equals(cp.required)) { m.requiredVars.add(cp); } else { // else add to the list optionalVars for optional property m.optionalVars.add(cp); } // if readonly, add to readOnlyVars (list of properties) if (Boolean.TRUE.equals(cp.isReadOnly)) { m.readOnlyVars.add(cp); } else { // else add to readWriteVars (list of properties) m.readWriteVars.add(cp); }这段逻辑可以精确解读为hasOnlyReadOnly翻转规则只要发现任何一个属性不是只读isReadOnly不为true就将模型的hasOnlyReadOnly置为false。反之若所有属性都是只读该标志保持true——这正是HasOnlyReadOnly这类模型在生成器内部被打上全只读标签的依据必填/可选分流属性按required列表进入requiredVars或optionalVars。HasOnlyReadOnly的两个属性都未出现在required中因此文档 Notes 列呈现[optional]读写属性分流只读属性进入readOnlyVars可写属性进入readWriteVars。模板层据此决定是否渲染 setter 等写入代码最终形成第二节中只有 getter、没有 setter的 Java 类。值得注意的是DefaultCodegen遍历时还顺带设置了cp.hasMore与cp.hasMoreNonReadOnly用于模板判断属性间是否需要分隔符说明只读标记不仅影响 setter 生成还会参与模板的循环渲染细节。四、定义源头如何在 OpenAPI/Swagger 定义中声明只读属性readOnly行为最终取决于 spec 文件中的readOnly: true声明。仓库测试 fixture 中有现成的样例可参照例如fixtures/immutable/specifications/v2/petstorefake.yaml 中Name模型的定义Name: description: Model for testing model name same as property name required: - name properties: name: type: integer format: int32 snake_case: readOnly: true type: integer format: int32 property: type: string 123Number: type: integer readOnly: true xml: name: Name从中可以归纳出与只读属性相关的实战要点声明方式在属性节点下加readOnly: true值必须为布尔true与type、format平级必填与只读的关系required与readOnly是两个正交维度。上例name为必填可写属性snake_case为只读可选属性二者互不影响但实际 API 设计中只读属性通常是服务端生成值如主键、创建时间不应同时声明为客户端必填对客户端与服务端生成的影响不同客户端生成器如本例的 okhttp-gson会省略只读属性的 setter而服务端生成器通常仍需要为只读字段保留读取能力只是写入路径不同。同一份 spec 面向不同目标语言/框架生成的代码形态由各语言生成器模板自行决定。同一 fixture 的 v2/petstorefake.yaml 中还包含大量readOnly: true用法如 L1128、L1135、L1318、L1326、L1329 等多处覆盖了只读属性与xml命名、数字型属性名等组合场景可作为学习生成行为的真实样本集。五、工程导航从 README 找到模型文档并验证生成约定在生成工程中模型文档并非孤立存在而是与 README 的模型索引相互链接。打开samples/client/petstore/java/okhttp-gson-parcelableModel/README.md可以看到模型清单中的条目- [HasOnlyReadOnly](https://link.gitcode.com/i/f081af001b6044e07f78098d55ac822c)也就是说在实际生成的客户端工程内部模型文档的相对路径为docs/HasOnlyReadOnly.md相对于工程根目录本文在仓库中的完整位置则是samples/client/petstore/java/okhttp-gson-parcelableModel/docs/HasOnlyReadOnly.md。你在自己的工程里做类似验证时可按以下三步走在 README 的模型列表中定位目标模型点击进入对应的docs/ModelName.md快速确认属性名、类型与[optional]/[required]标注在src/main/java/包路径/model/下打开同名 Java 类核对SerializedName、getter/setter 有无验证文档与代码的一致性若发现属性标注与预期不符例如漏了必填、只读属性意外生成了 setter回到 spec 定义检查required列表与readOnly: true是否书写正确再重新执行代码生成。六、小结从一行文档表看懂一个生成约定回到最初的文档——那张只有两行数据的属性表其实浓缩了 swagger-codegen 的完整约定链文档层面Name | Type | Description | Notes四列是每个生成模型文档的固定结构[optional]/[required]由 spec 的required列表驱动代码层面SerializedName绑定 JSON 键名只读属性只生成 getter 不生成 setterokhttp-gson-parcelableModel额外补齐Parcelable的writeToParcel/CREATOR生成器层面CodegenModel.readOnlyVars/hasOnlyReadOnly配合DefaultCodegen的属性遍历决定了模型是全只读还是可读写并驱动模板渲染出不同的 Java 代码。当你在生成代码中看到任何带readOnly: true的属性时只需对照本文的源码链路就能准确预判它会以何种形态出现在文档表、getter/setter 和序列化逻辑中。赞分享开发工具代码生成API设计【免费下载链接】swagger-codegenswagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.项目地址https://gitcode.com/gh_mirrors/sw/swagger-codegen点击查看免费下载相关推荐Swagger Codegen 生成 Java 模型文档解析以 okhttp-gson-parcelableModel 的 ModelApiResponse 为例Swagger Codegen 生成 Java 模型文档解析以 okhttp gson parcelableModel 的 ModelApiResponse开发工具代码生成API设计swagger-codegen 生成的 Java 枚举模型文档详解以 okhttp-gson-parcelableModel 的 Ints.md 为例swagger codegen 生成的 Java 枚举模型文档详解以 okhttp gson parcelableModel 的 Ints.md 为例 导读开发工具代码生成API设计Swagger Codegen 生成的 Java 模型文档深度解析以 okhttp-gson-parcelableModel 的 Name 模型为例Swagger Codegen 生成的 Java 模型文档深度解析以 okhttp gson parcelableModel 的 Name 模型为例 本文以开发工具代码生成API设计上一篇LFM2.5-8B-A1B-GGUF多语言支持详解中文、英文、日文等8种语言处理能力下一篇攻克TypeScript类型挑战手把手实现字符串数组最长公共前缀创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表