自定義swagger maven codegen外掛
專案中需要根據openapi 2.0介面定義自動生成指定框架程式碼,github中有對應的案例,不過生成的程式碼框架不符合當前需求,因此根據專案需要自定義了一個codegen外掛,這裡記錄下外掛流程
swagger-codegen專案github地址:https://github.com/swagger-api/swagger-codegen
maven外掛編寫過程
1、IDEA建立maven-plugin工程
2、指定packaging和artifactId
maven外掛packageing型別為maven-plugin,artifactId即為maven外掛的命名,按照官方規範,maven外掛命名建議為:xxxx-maven-plugin,這樣命名有兩個好處:
(1)maven-xxxx-plugin為maven官方外掛命名,使用這種命名方式可能侵權
(2)自定義外掛maven執行命令為mvn groupId:artifactId:goal,使用推薦命名方式,maven命令可以簡化為mvn xxxx:goal
3、繼承AbstactMojo自定義Mojo類
(1)@Mojo註解用來指定外掛goalPrefix和執行的生命週期
(2)@Parameter註解用來指定該外掛輸入引數
(3)execute()方法用來編寫maven外掛邏輯
4、maven工程依賴及注意事項
(1)基礎依賴
<dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.6.0</version> </dependency> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-project</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.6.0</version> </dependency> <!-- Mojo類註解需要新增的依賴 -->
(2)注意事項:如果外掛Mojo類中使用的java8語法,需要在build標籤中新增maven-plugin-plugin編譯依賴,並且顯式指定版本號為3.5.2及以上
swagger-codegen流程
1、新增swagger依賴
<dependency> <groupId>io.swagger.parser.v3</groupId> <artifactId>swagger-parser</artifactId> <version>2.0.20</version> </dependency> <dependency> <groupId>io.swagger.codegen.v3</groupId> <artifactId>swagger-codegen</artifactId> <version>3.0.21</version> </dependency>
2、定義mustache模板
swagger提供瞭解析mustache模板檔案的方法,通過解析yaml檔案定義及mustache模板,生成指定的java類;
mustache傳送門:https://github.com/mustache/mustache.github.com
舉例:生成api介面類mustache模板
package {{apiPackage}}; {{#importPackageList}} import {{className}};{{/importPackageList}} import javax.servlet.ServletException; public interface {{className}}Api { {{#pathGetEntity}} {{pathGetEntity.responseType}} {{pathGetEntity.methodName}}({{#pathGetEntity.params}}{{paramType}} {{paramName}}{{/pathGetEntity.params}}) throws ServletException; {{/pathGetEntity}}{{#pathDeleteEntity}} void {{pathDeleteEntity.methodName}}({{#pathDeleteEntity.params}}{{paramType}} {{paramName}}{{/pathDeleteEntity.params}}) throws ServletException; {{/pathDeleteEntity}}{{#pathPostEntity}} void {{pathPostEntity.methodName}}({{#pathPostEntity.params}}{{paramType}} {{paramName}}{{/pathPostEntity.params}}) throws ServletException; {{/pathPostEntity}}{{#pathPutEntity}} void {{pathPutEntity.methodName}}({{#pathPutEntity.params}}{{paramType}} {{paramName}}{{/pathPutEntity.params}}) throws ServletException; {{/pathPutEntity}} }
3、通過開源swagger解析yaml定義
private Swagger createSwagger() throws MojoExecutionException { String apiFileStr; try { File file = new File(this.inputSpec); apiFileStr = FileUtils.readFileToString(file, StandardCharsets.UTF_8).trim(); } catch (IOException e) { throw new MojoExecutionException("Read api file to string exception!"); } return new SwaggerParser().parse(apiFileStr); }
該swagger物件是基於openapi 2.0規範的解析物件,包含paths、definations等
4、根據輸入解析及mustache模板,生成對應的api介面類
private void writeToFile(Object context, String fileName, String templateName) { try { // 獲取模板資訊 String templateFileString = this.getTempFileString(templateName); // 生成模板 Template template = Mustache.compiler().compile(templateFileString); // 解析模板 String executeResult = template.execute(context); // 生成java類 String outputPath = this.getOutputFilePath(fileName, templateName); FileUtils.writeStringToFile(new File(outputPath), executeResult, StandardCharsets.UTF_8, true); } catch (Exception e) { e.printStackTrace(); } }
5、yaml定義及生成的api介面類
swagger: "2.0" info: title: Title description: Title version: 1.0.0 host: www schemes: - https basePath: /rest paths: /test/v1/user: post: tags: - "MyUser" summary: "建立使用者" operationId: "createUser" produces: - "application/json" consumes: - "application/json" parameters: - name: "user" in: body description: "建立使用者" required: true schema: $ref: '#/definitions/User' responses: 200: description: "建立使用者成功." put: tags: - "MyUser" summary: "修改使用者" operationId: "modifyUser" produces: - "application/json" consumes: - "application/json" parameters: - name: "user" in: body description: "修改使用者" required: true schema: $ref: '#/definitions/User' responses: 200: description: "修改使用者成功." /test/v1/user/{id}: delete: tags: - "MyUser" summary: "通過ID刪除使用者" operationId: "deleteUserById" produces: - "application/json" consumes: - "application/json" parameters: - name: "id" in: query description: "通過ID刪除使用者" required: true type: "integer" format: "int64" responses: 200: description: "Delete family members by person id" get: tags: - "MyUser" summary: "通過ID獲取使用者資訊" operationId: "getUserById" produces: - "application/json" consumes: - "application/json" parameters: - name: "id" in: query description: "通過ID獲取使用者資訊" required: true type: "integer" format: "int64" responses: 200: description: "Retrieves family members by person id" schema: $ref: '#/definitions/User' definitions: User: type: "object" required: - "id" - "firstName" - "lastName" - "dateOfBirth" - "gender" properties: id: type: "integer" format: "int64" firstName: type: "string" example: "John" lastName: type: "string" example: "Smith" dateOfBirth: type: "string" example: "1992-10-05"
package com.demo.api; import com.demo.model.User; import javax.servlet.ServletException; public interface MyUserApi { User getUserById(Integer id) throws ServletException; void deleteUserById(Integer id) throws ServletException; void createUser(User user) throws ServletException; void modifyUser(User user) throws ServletException; }
本文只是簡單記錄下通過swagger編寫maven外掛的過程,完整的程式碼見我的github
swagger-codegen外掛地址:https://github.com/bale1992/swagger-codegen-maven-plugin
測試工程地址:https://github.com/bale1992/swagger-codegen-maven-plugin-test