我使用swagger codegen生成jaxrs服务器端类以及客户端java类。
这是我用来生成类的命令
java -jar modules/swagger-codegen-distribution/target/swagger-codegen-distribution-2.1.2-M1.jar -i /Users/me/Workspace/swagger-codegen/samples/yaml/echo.yaml -l jaxrs -o samples/server/echo/java
生成的服务器代码有一个占位符来写我的“魔法”。
public Response echo(@ApiParam(value = "" )@HeaderParam("headerParam") String headerParam,
@ApiParam(value = "",required=true) @QueryParam("message") String message)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
我在“echo”方法中添加了“magic”并重新生成了代码,只是为了看到它被消灭了。避免丢失自定义代码的一种方法是修改codegen模板以生成接口而不是类。然后我可以在实现的类中拥有所有自定义代码。
我试图找出是否有一种方法可以保留自定义“魔法”,即使在重新生成代码之后,或者有更好的方法来处理这种情况,而不是更改模板以生成接口而不是类。
最新的Swagger Codegen大师允许您在代码生成期间指定.swagger-codegen-ignore(类似于.gitignore)不会覆盖的文件。
请拉一下最新的Swagger Codegen大师试一试。
更新:2018年5月,Swagger Codegen的大约50名顶级贡献者和模板创建者决定将Swagger Codegen分叉,以维护一个名为OpenAPI Generator的社区驱动版本。有关更多信息,请参阅Q&A。
你好, 也许四年之后,答案有点晚了,但迟到了,而不是永远。
如果你有一个正确的招摇文件(不仅是一个片段),如下所示
openapi: "3.0.0"
:
paths:
/example:
get:
operationId: showIt
:
并且你运行代码生成,在这个没有任何代码生成特定配置值的jaxs-jersey-server的解释中(你可以从Swagger editor下载),你得到了大量的java clases,如下所示:
io.swagger.api. ExampleApi
io.swagger.api. ExampleApiService
io.swagger.api.factories.ExampleApiServicefactory
io.swagger.api.impl. ExampleApiServiceImpl
在REST端点实现ExampleApiServiceImpl中,您可以看到更多或更少的内容,如下所示:
package io.swagger.api.impl;
:
import ... ;
:
@javax.annotation.Generated(...)
public
class ExampleApiServiceImpl
extends ExampleApiService
{
// ...
@Override
public
Response showIt( /* additional parameters , */ SecurityContext securityContext)
throws NotFoundException
{
// do some magic!
return Response.ok()
.entity(new ApiResponseMessage( ApiResponseMessage.OK
, "magic!"
)
)
.build();
}
// ...
}
你现在交换魔术评论吗?
// do some magic!
通过以下可能
String className = this.getClass().getSimpleName();
System.out.println("Entered REST endpoint: path=|" + className.substring(0, className.length() - 14) + "| operationId=|showId|");
如果在完成mvn clean package jetty:run
后从浏览器中调用端点,则应该会看到一条日志消息。但是,正如你意识到的那样,这不是一个好主意,因为在下一代之后,你的改变就消失了。
在这种情况下,手动更改生成的代码永远不是一个好主意,因为这必须得到很好的记录,以便未来的同事(可能在几个月或几年后甚至可能是你)甚至在星期一晚上的星期日半睡半醒下一代码生成后再次更改。但是我对不同代码生成器的20多年经验只说明了一件事:忘掉它吧!出于同样的原因,在第一代之后防止进一步发电并不是真正的目标导向,因为这也必须被广泛记录。否则调试小时超过调试小时可能会出现新功能无法解决的原因。
但这并非必要。 在生成的类io.swagger.api.ExampleApi中,您将找到如下所示的构造函数(好的,这是2019-05-17的状态。我不知道四年前它是否相同(或类似) )
package io.swagger.api;
:
import ... ;
:
@Path("/example")
@javax.annotation.Generated(...)
public class ExampleApi
{
private final ExampleApiService delegate;
public ExampleApi(@Context ServletConfig servletContext)
{
// ...
if (servletContext != null) {
String implClass = servletContext.getInitParameter("ExampleApi.implementation");
if (implClass != null && !"".equals(implClass.trim()))
{
try
{
delegate = (ExampleApiService) Class.forName(implClass).newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
// ...
}
// ...
}
代码的重要部分是servletContext.getInitParameter("...")
。如果现在在servlet配置中指定一个名为ExampleApi.implementation
的密钥,该密钥具有从ExampleApiService
派生的完全限定的java类名,那么您已经实现了自己的端点代码,这对于将来代码生成的覆盖是安全的。
为了完成这个例子,这个规范将在(额外生成,哎呀,抱歉,你不能拥有一切)web.xml
文件中。此文件包含以下内容:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
...
<load-on-startup>1</load-on-startup>
</servlet>
在这个xml片段中,您必须在句点(代表其他servlet配置设置)之后插入以下内容:
<init-param>
<param-name>ExampleApi.implementation</param-name>
<param-value>my.swagger.api.MyExample</param-value>
</init-param>
好看, 无论你现在是什么!
您可以在.swagger-codegen-ignore
文件中指定要忽略的文件
以下是qazxsw poi文件的示例自解释自动生成代码
.swagger-codegen-ignore
您可以在此下方添加一些行来忽略,例如我想忽略文件夹impl中的所有文件,所以我添加了以下行来做到这一点
# Swagger Codegen Ignore
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md