Swagger Codegen CLI Java Client - 如何正确使用它
我目前正在玩我的球衣2休息服务。为了更好地概述给定的服务(描述,类型等),我大量使用swagger(swagger-jersey2-jaxrs)。因此,我能够对我的服务描述(swagger.json)进行归纳,并且可以通过swagger ui查看和探索它们。
现在,我需要创建一些客户端来使用这些服务。我遇到了swagger codegen cli,这是一个很好的工具,可以生成你的客户端和许多不同的语言(在我的情况下是java)。我能够生成 API 客户端和正在使用的模型。
在这里,我面临第一个问题。REST 服务和 swagger 描述受 http 基本身份验证保护。我阅读了文档,它给了我一些提示,提示有可能使用基本身份验证。在这一点上,我不得不提到,从我的角度来看,文档非常差。它说:
-a , --auth 在远程获取 swagger 定义时添加授权标头。传入一个 URL 编码的 name:header 字符串,用逗号分隔多个值。
我想到的第一件事是像在http标头中传递一个字符串,但这不起作用,甚至谷歌搜索如何使用基本身份验证和swagger cli也没有产生一些明确的答案。经过多次尝试和错误(我使用的是CLI 2.1.2),我终于遇到了正确的格式:
java -jar swagger-codegen-cli-2.1.2.jar generate -a “Authorization: Basic YWRtaW46YWRtaW4=” -i http://localhost:8080/webproject/restapi/swagger.json -l java -o restclient
其中 YWRtaW46YWRtaW4= 是我案例中 admin:admin 的 base64 编码值。
目前为止,一切都好。生成的java客户端也必须使用基本的身份验证。我看了一下ApiClient和found setUsername和setPassword的方法。我认为这种方法使客户端能够使用基本的身份验证,但没有运气。
因此,我更深入地研究了生成的类,尤其是 ApiClient 和几个生成的 ApiService 类。我发现 setUsername 和 setPassword 没有效果,因为以下原因:
/**
* Helper method to set username for the first HTTP basic authentication.
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
其中,同时哈希映射被定义为:
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
身份验证哈希映射变得不可变,但为什么呢?目的是什么?此外,ApiClinet中没有生成所需身份验证对象的帮助器方法,因此我执行以下操作:
1)注释掉行身份验证 Collections.unmodifiableMap(authentications),以便哈希映射再次变得可修改
2) 手动创建所需的身份验证对象
HttpBasicAuth authentication = new HttpBasicAuth();
authentication.setUsername("admin");
authentication.setPassword("admin");
3) 将身份验证对象添加到 apiClients 身份验证哈希映射:
ApiClient apiClient = new ApiClient();
apiClient.setBasePath(basePath);
apiClient.getAuthentications().put("basic", authentication);
4) 修改 invokeApi Method (ApiClient.java)
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
String authNames2[] = {"basic"};
updateParamsForAuth(authNames2, queryParams, headerParams);
//updateParamsForAuth(authNames, queryParams, headerParams);
...
步骤 4 是必需的,因为 ApiServices 调用 apiClient 方法,如下所示:
String[] authNames = new String[] { };
String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
另一种可能的解决方案是在每个apiService中定义身份验证哈希映射的密钥,如下所示:
String[] authNames = new String[] { "basic" };
完成所有修改后,一切都按预期工作,但我不认为这是自动生成的rest客户端背后的想法。所以我的问题是:我是否遗漏了一些要点,或者我应该考虑swagger生成的客户端(在这种情况下是java)更像是正在开发的beta解决方案?请把我弄对,我认为整个swagger框架(jersey2支持,openapi,swaggerui,codegen)是一件很棒的事情,我很欣赏开发人员的努力,但我想正确使用codegen,我不认为背后的想法是必须以这种方式自定义生成的ApiClient和ApiServices。