summarize
unmixedmavenProject integration swagger3, project according to swagger3API definition specification definition api interface, by scanning the package path to generate json oryamlformat, which can be used for front-end presentations.
pom dependencies
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0"
xmlns:xsi="http:///2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.">
<modelVersion>4.0.0</modelVersion>
<groupId></groupId>
<artifactId>swagger3-generate-file</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- /artifact/.v3/swagger-jaxrs2 -->
<dependency>
<groupId>.v3</groupId>
<artifactId>swagger-jaxrs2</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>plexus-utils</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>.v3</groupId>
<artifactId>swagger-integration</artifactId>
<version>2.1.11</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
ApiResource
package ;
import ;
import .;
import .;
import .;
import .;
import .;
import ;
import ;
import ;
import ;
@Path("/students")
public class StudentResource {
@GET
@Path("/getStudentById/{student_id}")
@Operation(summary = "according toidAccess to student information",
tags = {"students"})
@ApiResponses(value = {
@ApiResponse(responseCode = "200",content = @Content(mediaType = "application/json",schema = @Schema(implementation = )),description = "Successful query"),
@ApiResponse(responseCode = "404",description = "Students do not exist")
})
public StudentDTO getStudentById(@PathParam("student_id") Long studentId){
return new StudentDTO();
}
@GET
@Path("/listStudents")
@Operation(summary = "Query Student List",
tags = {"students"})
@ApiResponses(value = {
@ApiResponse(responseCode = "200",content = @Content(mediaType = "application/json",schema = @Schema(implementation = )),description = "Successful query"),
})
public StudentDTO listStudents(@QueryParam("pageNo") Integer pageNo,
@QueryParam("pageSize")Integer pageSize,
@QueryParam("name") String name){
return new StudentDTO();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
openapi basic information configuration file()
openapi: 3.0.1
info.
title: Student API
description: Student API documentation
contact.
email: 13928121916@
version: "1.1"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
Document Generation Class
package ;
import ;
import ;
import .;
import .;
import .;
import .;
import .v3.;
import .;
import .;
import .;
import .;
import .slf4j.Slf4j;
import .;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import .*;
import ;
import static ;
@Slf4j
public class GenerateOpenApiFileTest {
private static String encoding = "UTF-8";
private SwaggerConfiguration config;
private String contextId;
private String filterClass;
private String outputPath = "src/test/resources";
//Packages that need to be scanned to generate files
private Set<String> resourcePackages ;
private enum Format {JSON,YAML,JSONANDYAML}
//Name of the generated file
private String outputFileName="generateopenapi";
//Format of generated documents
private Format outputFormat = ;
private Boolean prettyPrint;
private Boolean sortOutput;
private Boolean alwaysResolveAppPath;
private Boolean readAllResources;
@Test
public void createOpenApiFile() throws MojoFailureException {
String baseInfoPath = "src/main/resources/";
resourcePackages = new HashSet<>();
("");
Optional<OpenAPI> openapiInput = readStructuredDataFromFile(baseInfoPath, , "openapiFilePath");
config = mergeConfig((null),new SwaggerConfiguration());
setDefaultsIfMissing(config);
JaxrsOpenApiContextBuilder builder = new JaxrsOpenApiContextBuilder<>().openApiConfiguration(config);
if((contextId)){
(contextId);
}
OpenApiContext context = null;
try {
context = (true);
OpenAPI openAPI = ();
//Filtering of documents that do not need to be generatedclass
if((())){
try {
OpenAPISpecFilter filterImpl = (OpenAPISpecFilter) ().getClassLoader().loadClass(()).newInstance();
SpecFilter f = new SpecFilter();
openAPI = (openAPI, filterImpl, new HashMap<>(), new HashMap<>(),
new HashMap<>());
} catch (Exception e) {
( "Error applying filter to API specification" , e);
throw new MojoExecutionException("Error applying filter to API specification: " + (), e);
}
}
String openapiJson = null;
String openapiYaml = null;
if ((outputFormat) || (outputFormat)) {
if (() != null && ()) {
openapiJson = ().writer(new DefaultPrettyPrinter()).writeValueAsString(openAPI);
} else {
openapiJson = ().writeValueAsString(openAPI);
}
}
if ((outputFormat) || (outputFormat)) {
if (() != null && ()) {
openapiYaml = ().writer(new DefaultPrettyPrinter()).writeValueAsString(openAPI);
} else {
openapiYaml = ().writeValueAsString(openAPI);
}
}
Path path = (outputPath, "temp");
final File parentFile = ().getParentFile();
if (parentFile != null) {
();
}
if (openapiJson != null) {
path = (outputPath, outputFileName + ".json");
(path, ((encoding)));
( "JSON output: " + ().getCanonicalPath());
}
if (openapiYaml != null) {
path = (outputPath, outputFileName + ".yaml");
(path, ((encoding)));
( "YAML output: " + ().getCanonicalPath());
}
} catch (OpenApiConfigurationException | MojoExecutionException | JsonProcessingException e) {
();
} catch (IOException e) {
();
}
}
private void setDefaultsIfMissing(SwaggerConfiguration config) {
if (prettyPrint == null) {
prettyPrint = ;
}
if (readAllResources == null) {
readAllResources = ;
}
if (sortOutput == null) {
sortOutput = ;
}
if (alwaysResolveAppPath == null) {
alwaysResolveAppPath = ;
}
if (() == null) {
(prettyPrint);
}
if (() == null) {
(readAllResources);
}
if (() == null) {
(sortOutput);
}
if (() == null) {
(alwaysResolveAppPath);
}
}
private SwaggerConfiguration mergeConfig(OpenAPI openAPIInput, SwaggerConfiguration config) {
// overwrite all settings provided by other maven config
if ((filterClass)) {
(filterClass);
}
/*if (isCollectionNotBlank(ignoredRoutes)) {
(ignoredRoutes);
}*/
if (prettyPrint != null) {
(prettyPrint);
}
if (sortOutput != null) {
(sortOutput);
}
if (alwaysResolveAppPath != null) {
(alwaysResolveAppPath);
}
if (readAllResources != null) {
(readAllResources);
}
/* if ((readerClass)) {
(readerClass);
}
if ((scannerClass)) {
(scannerClass);
}
if (isCollectionNotBlank(resourceClasses)) {
(resourceClasses);
}*/
if (openAPIInput != null) {
(openAPIInput);
}
if (isCollectionNotBlank(resourcePackages)) {
(resourcePackages);
}
/*if ((objectMapperProcessorClass)) {
(objectMapperProcessorClass);
}
if (isCollectionNotBlank(modelConverterClasses)) {
(modelConverterClasses);
}*/
return config;
}
private boolean isCollectionNotBlank(Collection<?> collection) {
return collection != null && !();
}
/**
* Read the content of given file as either json or yaml and maps it to given class
*
* @param filePath to read content from
* @param outputClass to map to
* @param configName for logging, what user config will be read
* @param <T> mapped type
* @return empty optional if not path was given or the file was empty, read instance otherwis
* @throws MojoFailureException if given path is not file, could not be read or is not proper json or yaml
*/
private <T> Optional<T> readStructuredDataFromFile(String filePath, Class<T> outputClass, String configName)
throws MojoFailureException {
try {
// ignore if config is not provided
if ((filePath)) {
return ();
}
Path pathObj = (filePath);
// if file does not exist or is not an actual file, finish with error
if (!().exists() || !().isFile()) {
throw new IllegalArgumentException(
format("passed path does not exist or is not a file: '%s'", filePath));
}
String fileContent = new String((pathObj), encoding);
// if provided file is empty, log warning and finish
if ((fileContent)) {
(format("It seems that file '%s' defined in config %s is empty",
(), configName));
return ();
}
// get mappers in the order based on file extension
List<BiFunction<String, Class<T>, T>> mappers = getSortedMappers(pathObj);
T instance = null;
Throwable caughtEx = null;
// iterate through mappers and see if one is able to parse
for (BiFunction<String, Class<T>, T> mapper : mappers) {
try {
instance = (fileContent, outputClass);
break;
} catch (Exception e) {
caughtEx = e;
}
}
// if no mapper could read the content correctly, finish with error
if (instance == null) {
if (caughtEx == null) {
caughtEx = new IllegalStateException("undefined state");
}
(format("Could not read file '%s' for config %s", (), configName), caughtEx);
throw new IllegalStateException((), caughtEx);
}
return (instance);
} catch (Exception e) {
(format("Error reading/deserializing config %s file", configName), e);
throw new MojoFailureException((), e);
}
}
/**
* Get sorted list of mappers based on given filename.
* <p>
* Will sort the 2 supported mappers: json and yaml based on what file extension is used.
*
* @param pathObj to get extension from.
* @param <T> mapped type
* @return list of mappers
*/
private <T> List<BiFunction<String, Class<T>, T>> getSortedMappers(Path pathObj) {
String ext = (());
boolean yamlPreferred = false;
if (("yaml") || ("yml")) {
yamlPreferred = true;
}
List<BiFunction<String, Class<T>, T>> list = new ArrayList<>(2);
((content, typeClass) -> {
try {
return ().readValue(content, typeClass);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
((content, typeClass) -> {
try {
return ().readValue(content, typeClass);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
if (yamlPreferred) {
(list);
}
return (list);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
Demo project gitee address
References.
/swagger-api/swagger-core/blob/master/modules/swagger-maven-plugin/src/main/java/io/swagger/v3/plugin/maven/