Generate Spring Boot REST Client with Swagger > http://www.baeldung.com/spring-boot-rest-client-swagger-codegen
swagger-codegen-maven-plugin > https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen-maven-plugin/README.md
This article will automatically build a full REST WS client from a OpenAPI (former swagger) spec file.
Note: Although this technique is not specific to Spring Boot, the example assumes we're working on an Spring Boot project.
Warning: This sub page uses swagger-codegen-maven-plugin; see the newer openapi-generator-maven-plugin
Place the OpenAPI spec file inside the Maven project folder:
src/main/resources/openapis/
Note: For the example, the spec file name "BOF-20180712.json" will be used.
Remark: It should work in the same way if using a spec file in .yaml format instead of .json.
At the 'properties' section, declare the swagger-codegen version:
<swagger.codegen.version>2.3.1</swagger.codegen.version>
At the 'build.pluginManagements.plugins' section, add Eclipse lifecycle mapping:
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<versionRange>[${swagger.codegen.version},)</versionRange>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
At the 'build.plugins' section, add the generation for Java sources out of the OpenAPI spec file:
<plugin>
<!-- Generate Java Client for OpenAPI REST WS: BOF -->
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>${swagger.codegen.version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/openapis/BOF-20180712.json</inputSpec>
<language>java</language>
<library>resttemplate</library>
<modelPackage>${project.groupId}.bof.model</modelPackage>
<apiPackage>${project.groupId}.bof.api</apiPackage>
<invokerPackage>${project.groupId}.bof.invoker</invokerPackage>
<configOptions>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
Try to build the project for checking if any additional dependency is missing (it might depend on the specific OpenAPI spec file being used).
If project compilation fails, probably swagger-codegen generated Java sources with "import" statements pointing to dependencies not available in the project.
Fortunately, swagger-codegen also generated a pom.xml file with all the dependencies used by the generated sources:
target/generated-sources/swagger/pom.xml
In our example, a dependency for the deserialization of time fields is needed, so let's added to the project pom.xml:
<dependency>
<groupId>com.github.joschi.jackson</groupId>
<artifactId>jackson-datatype-threetenbp</artifactId>
<version>2.6.4</version>
</dependency>
At section "build.plugins":
<plugin>
<!-- adding generated source (it adds a new build_class_path to the project) -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/swagger/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Remark: When using Eclipse 4.8, the plugin version inherited from Spring Boot might not be compatible. If that happens, override it in the 'properties' section as follows:
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
Create this file at the same level than the main Spring Boot application one (annotated with @SpringBoot application):
package edu.cou.gpra_doc;
import edu.cou.igpra.bof.api.ProgramasApi;
import edu.cou.igpra.bof.invoker.ApiClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BofIntegrationConfig {
//REST WS Endpoint 'basePath'
private static final String bofWsBasePath = "https://bofws-bofws-test.cloudapps.uoc.es";
@Bean
public ProgramasApi programasApi() {
return new ProgramasApi(apiClient());
}
/**
* The ApiClient class is used for configuring authentication, the base path of
* the API, common headers, and it’s responsible for executing all API
* requests.<br>
*/
@Bean
public ApiClient apiClient() {
ApiClient apiClient = new ApiClient();
// Endpoint basePath
apiClient.setBasePath(bofWsBasePath);
/*- Sample oauth authentication
OAuth petStoreAuth = (OAuth) apiClient.getAuthentication("petstore_auth");
petStoreAuth.setAccessToken("special-key");
*/
return apiClient;
}
}
Add the annotation to the Spring Boot application class annotated with "@SpringBootApplication":
...
@SpringBootApplication
@Import(BofIntegrationConfig.class)
...
@Service
public class BofHelper implements Bof {
//Inject the generated OpenAPI client
@Autowired
ProgramasApi programasApi;
//Method that invokes a remote operation via the generated client
public Programa getById(Long id, String X_COU_SCOPE, String idioma, String entity)
throws RestClientException {
Programa p = programasApi.getByIdUsingGET(id, X_COU_SCOPE, idioma, entity);
return p;
}
}
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
;
}