前言:
之前工作中使用的都是Spring框架,现在工作中用到JFinal,于是参考了JFinal的文档写了小demo,一步一步的走下去,难以理解并不常用的先行跳过了。
在实际工作中,整理接口文档向来是一个比较费时的活儿。在SpringBoot中使用Swagger来整理接口文档,借鉴一篇《Jfinal集成Swagger 极简配置》的网上的实践,我自己实践JFinal集成Swagger并记录(期间遇到很多的坑)。限于自己的水平,如有错漏不当之处,还请不吝指教。
正文:
一、引入JFinal-Swagger依赖
<dependency>
<groupId>live.autu</groupId>
<artifactId>jfinal-swagger</artifactId>
<version>1.0.0</version>
</dependency>
二、下载UI文件到项目中
view.7z 下载地址:https://wwe.lanzous.com/ignP3j80xaf
swagger.7z 下载地址:https://wwe.lanzous.com/iycnPj80x9e
解压后复制进项目中
大家可以参考我的目录配置:
三、路由配置
视图路径=BaseViewPath+viewPath+view
setBaseViewPath()方法将后面的目录追加在src/main/webapp目录下(应该是指向了 undertow.resourcePath 配置中的第一个有效目录)。
public class SwaggerRoutes extends Routes { @Override public void config() { setBaseViewPath("/views"); add("/swagger", SwaggerController.class,""); } }
public void configRoute(Routes routes) { //配置路由 routes.add(new SwaggerRoutes()); }
四、插件配置
注册Swagger插件
注意点:
setSchemes设置swagger协议集合 http/https/...
setHost中的套接字必须与undertow启动的host一致,不然会出现跨域问题(关于为什么localhost可以,而127.0.0.1不行,这个我不太清楚,网上查了也没有确切的回答)
public void configPlugin(Plugins plugins) { plugins.add(new SwaggerPlugin(new SwaggerDoc().setBasePath("/").setHost("localhost:8097"). setSchemes(Arrays.asList("http")).setSwagger("2.0") .setInfo(new SwaggerApiInfo("全宇宙最牛逼的Jfinal开发脚手架", "1.0", "Jfinal Swagger", "")))); }
在undertow.txt中增加
undertow.hotSwapClassPrefix=live.autu.plugin.jfinal.swagger
至此,Swagger配置完成。
===========================================================================
以下展示我的undertow.txt的配置
# true undertow.devMode=true undertow.port=8097 undertow.host=0.0.0.0 # swagger undertow.hotSwapClassPrefix=live.autu.plugin.jfinal.swagger # context path #undertow.contextPath=/abc undertow.resourcePath = src/main/webapp, classpath:static # gzip undertow.gzip.enable=true # -11 91 9 undertow.gzip.level=-1 # undertow.gzip.minLength=1024 # session #undertow.session.timeout=1800 # session session truedevMode#undertow.session.hotSwap=true # ssl undertow.ssl.enable=false # ssl 443 undertow.ssl.port=443 # PKCS12 undertow.ssl.keyStoreType=PKCS12 # undertow.ssl.keyStore=demo.pfx # undertow.ssl.keyStorePassword=123456 # undertow.ssl.keyAlias=demo # ssl http2chrome : chrome://net-internals/#http2 undertow.http2.enable=true # ssl http https undertow.http.toHttps=false # ssl http https 302 undertow.http.toHttpsStatusCode=302 # ssl http undertow.http.disable=false
五、Swagger的使用
这部分内容转载于:https://juejin.cn/post/6844903901724950535
@Api
用在类上,该注解将一个Controller(Class)标注为一个swagger资源(API)。在默认情况下,Swagger-Core只会扫描解析具有@Api注解的类,而会自动忽略其他类别资源(JAX-RS endpoints,Servlets等等)的注解。该注解包含以下几个重要属性
tags API分组标签。具有相同标签的API将会被归并在一组内展示。
value 如果tags没有定义,value将作为Api的tags使用
description API的详细描述,在1.5.X版本之后不再使用,但实际发现在2.0.0版本中仍然可以使用
@ApiOperation
在指定的(路由)路径上,对一个操作或HTTP方法进行描述。具有相同路径的不同操作会被归组为同一个操作对象。不同的HTTP请求方法及路径组合构成一个唯一操作。此注解的属性有:
value 对操作的简单说明,长度为120个字母,60个汉字。
notes 对操作的详细说明。
httpMethod HTTP请求的动作名,可选值有:"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS" and "PATCH"。
code 默认为200,有效值必须符合标准的HTTP Status Code Definitions。
@ApiImplicitParams
用在方法上,注解ApiImplicitParam的容器类,以数组方式存储。
@ApiImplicitParam
对API的单一参数进行注解。虽然注解@ApiParam同JAX-RS参数相绑定,但这个@ApiImplicitParam注解可以以统一的方式定义参数列表,也是在Servelet及非JAX-RS环境下,唯一的方式参数定义方式。注意这个注解@ApiImplicitParam必须被包含在注解@ApiImplicitParams之内。可以设置以下重要参数属性:
name 参数名称
value 参数的简短描述
required 是否为必传参数
dataType 参数类型,可以为类名,也可以为基本类型(String,int、boolean等)
paramType 参数的传入(请求)类型,可选的值有path, query, body, header or form。
@ApiParam
增加对参数的元信息说明。这个注解只能被使用在JAX-RS 1.x/2.x的综合环境下。其主要的属性有
required 是否为必传参数,默认为false
value 参数简短说明
@ApiResponses
注解@ApiResponse的包装类,数组结构。即使需要使用一个@ApiResponse注解,也需要将@ApiResponse注解包含在注解@ApiResponses内。
@ApiResponse
描述一个操作可能的返回结果。当REST API请求发生时,这个注解可用于描述所有可能的成功与错误码。可以用,也可以不用这个注解去描述操作的返回类型,但成功操作的返回类型必须在@ApiOperation中定义。如果API具有不同的返回类型,那么需要分别定义返回值,并将返回类型进行关联。但Swagger不支持同一返回码,多种返回类型的注解。注意:这个注解必须被包含在@ApiResponses注解中。
code HTTP请求返回码。有效值必须符合标准的HTTP Status Code Definitions。
message 更加易于理解的文本消息
response 返回类型信息,必须使用完全限定类名,比如“com.xyz.cc.Person.class”。
responseContainer 如果返回类型为容器类型,可以设置相应的值。有效值为 "List", "Set" or "Map",其他任何无效的值都会被忽略。
Model注解
对于Model的注解,Swagger提供了两个:@ApiModel及@ApiModelProperty,分别用以描述Model及Model内的属性。
@ApiModel
描述一个Model的信息(一般用在请求参数无法使用@ApiImplicitParam注解进行描述的时候)
提供对Swagger model额外信息的描述。在标注@ApiOperation注解的操作内,所有的类将自动被内省(introspected),但利用这个注解可以做一些更加详细的model结构说明。主要属性有:
value model的别名,默认为类名
description model的详细描述
@ApiModelProperty
描述一个model的属性
对model属性的注解,主要的属性值有:
value 属性简短描述
example 属性的示例值
required 是否为必须值
六、demo
1.数据库表 org_user(不太规范,如果按照Jfinal的标准应该字段小写并用下划线)
2.实体类
public class User extends Model<User> { }
3.Controller
注意点:
dataType 的值首字母必须小写(如:integer,string,...),不然的话当设置为require=true时,校验会始终过不去。
其实在Jfinal中ActionKey在配置了控制器路由后,可以不必配置。但是使用swagger时,swagger的swagger-api扫描被@Api注解的控制器时,找不到@ActionKey注解的方法时会抛异常,所以我这里配置了ActionKey。
@Api(tags = {"Jfinal诸多特性实践控制层"}) public class TestSwaggerController extends Controller { /** * * 测试编码 */ @ApiOperation(methods = {RequestMethod.POST},description = "测试Swaggger",consumes = {"application/x-www-form-urlencoded"}) @ApiImplicitParams({ @ApiImplicitParam(name="NAME",description = "用户的姓名信息",required=true,dataType="string"), @ApiImplicitParam(name="AGE",description = "用户的年龄信息",required=true,dataType="integer",defaultValue = "0"), @ApiImplicitParam(name="USERID",description = "用户Id",required = true,dataType ="string",defaultValue =""), @ApiImplicitParam(name="CREATETIME",description = "创建时间",required = true,dataType = "string") }) @ApiResponses({ @ApiResponse(code="200",message = "成功"), @ApiResponse(code="3001",message = "系统异常") }) @Before(Tx.class) @ActionKey("/sw/testSwagger") public void testSwagger(@Para("") User user){ Map<String,Object> result=new HashMap<>(); result.clear(); try{ String name = user.getStr("NAME"); System.out.println(name); user.save(); PublicMethod.success(result,user); }catch (Exception e){ e.printStackTrace(); PublicMethod.server_error(result); throw e; }finally { renderJson(result); } } }
4.路由配置
public void configRoute(Routes routes) { //配置路由 routes.add(new AdminRoutes()); routes.add(new SwaggerRoutes()); }
public class AdminRoutes extends Routes { @Override public void config() { setBaseViewPath("/admin"); add("/sw", TestSwaggerController.class); } }
public class SwaggerRoutes extends Routes { @Override public void config() { setBaseViewPath("/views"); add("/swagger", SwaggerController.class,""); } }
5.启动并访问Swagger host/swagger
本例中:http://localhost:8097/swagger
测试接口:
执行结果: