Jan 01, 1970
要在事件驱动架构的情况下生成文档,有 。 AsyncAPI 是一项开源计划,旨在改善事件驱动架构 (EDA) 的当前状态。 AsyncApi 有几个 Java 工具,可让您从代码生成文档。在本文中,我描述了如何设置这些springwolf工具之一。
{ "service": { "serviceVersion": "2.0.0", "info": { //block with service info }, "servers": { "kafka": { //describe of kafka connection } }, "channels": { "kafka-channel": { "subscribe": { //... "message": { "oneOf": [ { "name": "pckg.test.TestEvent", "title": "TestEvent", "payload": { "$ref": "#/components/schemas/TestEvent" } } ] } }, //... } }, "components": { "schemas": { "TestEvent": { //jsonschema of component } } } } }
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class TestEvent implements Serializable { private String id; private LocalDateTime occuredOn; private TestEvent.ValueType valueType; private Map<String, Boolean> flags; private String value; public enum ValueType { STRING("STRING"), BOOLEAN("BOOLEAN"), INTEGER("INTEGER"), DOUBLE("DOUBLE"); private final String value; public ValueType(String value) { this.value = value; } } }
{ "service": { //... "components": { "schemas": { "TestEvent": { "type": "object", "properties": { "id": { "type": "string", "exampleSetFlag": false }, "occuredOn": { "type": "string", "format": "date-time", "exampleSetFlag": false }, "valueType": { "type": "string", "exampleSetFlag": false, "enum": [ "STRING", "BOOLEAN", "INTEGER", "DOUBLE" ] }, "flags": { "type": "object", "additionalProperties": { "type": "boolean", "exampleSetFlag": false }, "exampleSetFlag": false }, "value": { "type": "string", "exampleSetFlag": false } }, "example": { "id": "string", "occuredOn": "2016-07-20T15:49:04", "valueType": "STRING", "flags": { "additionalProp1": true, "additionalProp2": true, "additionalProp3": true } }, "exampleSetFlag": true } } } } }
在生成 DTO 类时,我们会得到如下的类结构。您可以看到 Enum 的处理方式与原始版本一样,但是Map<String, Boolean>类型的集合已变成单独的类 Flags 并且集合本身的整个值将落入Flags.additionalProperties字段中。
package pckg.test; // import @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "id", "occuredOn", "valueType", "flags", "value" }) @Generated("jsonschema2pojo") public class TestEvent implements Serializable { @JsonProperty("id") private String id; @JsonProperty("occuredOn") private LocalDateTime occuredOn; @JsonProperty("valueType") private TestEvent.ValueType valueType; @JsonProperty("flags") private Flags flags; @JsonProperty("value") private String value; @JsonIgnore private Map<String, Object> additionalProperties = new LinkedHashMap<String, Object>(); private final static long serialVersionUID = 73777748L; // Getters ans Setters @Generated("jsonschema2pojo") public enum ValueType { STRING("STRING"), BOOLEAN("BOOLEAN"), INTEGER("INTEGER"), DOUBLE("DOUBLE"); private final String value; private final static Map<String, TestEvent.ValueType> CONSTANTS = new HashMap<String, TestEvent.ValueType>(); static { for (TestEvent.ValueType c: values()) { CONSTANTS.put(c.value, c); } } ValueType(String value) { this.value = value; } @Override public String toString() { return this.value; } @JsonValue public String value() { return this.value; } @JsonCreator public static TestEvent.ValueType fromValue(String value) { TestEvent.ValueType constant = CONSTANTS.get(value); if (constant == null) { throw new IllegalArgumentException(value); } else { return constant; } } } } @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ }) @Generated("jsonschema2pojo") public class Flags implements Serializable { @JsonIgnore private Map<String, Boolean> additionalProperties = new LinkedHashMap<String, Boolean>(); private final static long serialVersionUID = 74717740L; //getters and setters }
@NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Getter @Setter(AccessLevel.PROTECTED) @EqualsAndHashCode @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type", visible = true, defaultImpl = ChangedEvent.class ) @JsonSubTypes(value = { @JsonSubTypes.Type(name = ChangedEvent.type, value = ChangedEvent.class), @JsonSubTypes.Type(name = DeletedEvent.type, value = DeletedEvent.class) }) @JsonIgnoreProperties(ignoreUnknown = true) @Schema(oneOf = {ChangedEvent.class, DeletedEvent.class}, discriminatorProperty = "type", discriminatorMapping = { @DiscriminatorMapping(value = ChangedEvent.type, schema = ChangedEvent.class), @DiscriminatorMapping(value = DeletedEvent.type, schema = DeletedEvent.class), }) public abstract class DomainEvent { @Schema(required = true, nullable = false) private String id; @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime occuredOn = LocalDateTime.now(); public abstract String getType(); } /** * Subtype ChangedEvent */ public class ChangedEvent extends DomainEvent implements Serializable { public static final String type = "CHANGED_EVENT"; private String valueId; private String value; } /** * Subtype DeletedEvent */ public class DeletedEvent extends DomainEvent implements Serializable { public static final String type = "DELETED_EVENT"; private String valueId; }
"components": { "schemas": { "ChangedEvent": { "type": "object", "properties": { "id": { "type": "string", "exampleSetFlag": false }, "occuredOn": { "type": "string", "format": "date-time", "exampleSetFlag": false }, "value": { "type": "string", "exampleSetFlag": false }, "valueId": { "type": "string", "exampleSetFlag": false }, "type": { "type": "string", "exampleSetFlag": false } }, "example": { "id": "string", "occuredOn": "2016-07-20T15:49:04", "value": "string", "valueId": "string", "type": "CHANGED_EVENT" }, "exampleSetFlag": true }, "DeletedEvent": { "type": "object", "properties": { "id": { "type": "string", "exampleSetFlag": false }, "occuredOn": { "type": "string", "format": "date-time", "exampleSetFlag": false }, "valueId": { "type": "string", "exampleSetFlag": false }, "type": { "type": "string", "exampleSetFlag": false } }, "example": { "id": "string", "occuredOn": "2016-07-20T15:49:04", "valueId": "string", "type": "DELETED_EVENT" }, "exampleSetFlag": true }, "DomainEvent": { "type": "object", "properties": { "id": { "type": "string", "exampleSetFlag": false }, "occuredOn": { "type": "string", "format": "date-time", "exampleSetFlag": false }, "type": { "type": "string", "exampleSetFlag": false } }, "example": { "id": "string", "occuredOn": "2016-07-20T15:49:04", "type": "string" }, "discriminator": { "propertyName": "type", "mapping": { "CHANGED_EVENT": "#/components/schemas/ChangedEvent", "DELETED_EVENT": "#/components/schemas/DeletedEvent" } }, "exampleSetFlag": true, "oneOf": [ { "$ref": "#/components/schemas/ChangedEvent", "exampleSetFlag": false }, { "$ref": "#/components/schemas/DeletedEvent", "exampleSetFlag": false } ] } } }
package pckg.test; // import @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "id", "occuredOn", "type" }) @Generated("jsonschema2pojo") @JsonTypeInfo(property = "type", use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true) @JsonSubTypes({ @JsonSubTypes.Type(name = "CHANGED_EVENT", value = ChangedEvent.class), @JsonSubTypes.Type(name = "DELETED_EVENT", value = DeletedEvent.class) }) public class DomainEvent implements Serializable { @JsonProperty("id") protected String id; @JsonProperty("occuredOn") protected LocalDateTime occuredOn; @JsonProperty("type") protected String type; @JsonIgnore protected Map<String, Object> additionalProperties = new LinkedHashMap<String, Object>(); protected final static long serialVersionUID = 46991903L; //getters and setters } // import @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "id", "occuredOn", "valueId", "type" }) @Generated("jsonschema2pojo") public class DeletedEvent extends DomainEvent implements Serializable { @JsonProperty("id") private String id; @JsonProperty("occuredOn") private LocalDateTime occuredOn; @JsonProperty("valueId") private String valueId; @JsonProperty("type") private String type; @JsonIgnore private Map<String, Object> additionalProperties = new LinkedHashMap<String, Object>(); private final static long serialVersionUID = 73263837L; // getters and setters } package pckg.test; //import @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "id", "occuredOn", "value", "type" }) @Generated("jsonschema2pojo") public class ChangedEvent extends DomainEvent implements Serializable { @JsonProperty("id") private String id; @JsonProperty("occuredOn") private LocalDateTime occuredOn; @JsonProperty("value") private String value; @JsonProperty("type") private String type; @JsonIgnore private Map<String, Object> additionalProperties = new LinkedHashMap<String, Object>(); private final static long serialVersionUID = 5446866391322866265L; //getters and setters }
plugins { id 'io.github.stepanovd.springwolf2dto' version '1.0.1-alpha' } springWolfDoc2DTO{ url = '//localhost:8080/springwolf/docs' targetPackage = 'example.package' documentationTitle = 'my-service' targetDirectory = project.layout.getBuildDirectory().dir("generated-sources") }
./gradle -q generateDTO
在本文中,我描述了如何使用springwolfdocs2dto插件基于 AsyncApi 文档生成新的 DTO 类。同时,新的类将根据原始继承并包含杰克逊注释以进行正确的反序列化。我希望你发现这个插件对你有用。