前言
最近公司着手开发一个CRM的系统,使用Jfinal开发的, 基于原系统做业务改造,为了方便后续前后端对接,打算集成Swagger进来,网上也是一顿找资料,有一些不错的集成方案,但是中间还是不可避免的踩了一堆坑,这里整体的在梳理一下,做个记录。
先上个效果图:
正文
1.引入依赖
<dependency>
<groupId>live.autu</groupId>
<artifactId>jfinal-swagger</artifactId>
<version>1.0.0</version>
</dependency>
2.下载UI文件到项目中
提取链接:https://pan.baidu.com/s/1Sb7BmmWEOeKsdJzuFXFNhQ
提取码:7176
下载后按如下路径进行配置:
webapp
static
swagger
favicon-16x16.png
...
swagger-ui.js.map
WEB-INF
views
swagger
index.html
3.增加Swagger路由配置
以第二步的形式配置的目录结构,可直接使用如下路由配置
/**
* 配置路由
*/
@Override
public void configRoute(Routes me) {
//me.add(new AdminRouter());
//Swagger路由配置
me.add(new SwaggerRoutes());
}
也可自行配置路由信息
public class SwaggerRoutes extends Routes {
@Override
public void config() {
setBaseViewPath("/WEB-INF/views");
add("/swagger", SwaggerController.class);
}
}
4.插件配置
添加配置文件:swagger.txt
basePath=/
host=127.0.0.1:8080
version=2.0
info.description=全宇宙最牛逼的Jfinal开发脚手架
info.version=1.0
info.title=Jfinal Swagger
将Swagger插件注册到Jfinal配置中
/**
* 配置插件
*/
@Override
public void configPlugin(Plugins me) {
me.add(new SwaggerPlugin());
}
或者通过代码直接配置
/**
* 配置插件
*/
@Override
public void configPlugin(Plugins me) {
me.add(new SwaggerPlugin(new SwaggerDoc().setBasePath("/").setHost("127.0.0.1").setSwagger("2.0")
.setInfo(new SwaggerApiInfo("全宇宙最牛逼的Jfinal开发脚手架", "1.0", "Jfinal Swagger", ""))));
}
5.配置undertow.txt
新增如下配置:
undertow.hotSwapClassPrefix=live.autu.plugin.jfinal.swagger
6.可用注解
常用的有如下四种注解,使用方式与swagger-annotation一致:
@Api
@ApiOperation
@ApiImplicitParams
@ApiImplicitParam
7.注解使用示例
/**
* @author Ivan
* @date 2020/4/1 12:47
* @Description 任务提醒控制层
*/
@Api(description="任务提醒接口管理")
public class RemindController extends Controller {
@Inject
private RemindService remindService;
/**
* @author Ivan
* 设置任务提醒
* @param taskRemind 任务提醒对象
*/
@ApiOperation(methods=RequestMethod.POST, description="设置任务提醒")
@ApiImplicitParams({
@ApiImplicitParam(name="taskRemind", description="任务提醒对象")
})
public void setRemind(@Para("") TaskRemind taskRemind){
renderJson(remindService.setRemind(taskRemind));
}
/**
* @author Ivan
* 根据任务id查询任务提醒数据
* @param taskId 任务编号
*/
@ApiOperation(methods=RequestMethod.POST, description="根据任务id查询任务提醒数据")
@ApiImplicitParams({
@ApiImplicitParam(name="taskId", description="任务编号")
})
public void queryByTaskId(@Para("taskId")Integer taskId){
renderJson(remindService.queryByTaskId(taskId));
}
}
结语
虽然在集成好了之后整理这份记录,流程很简单清晰,但是在实际集成过程中还是有很多的问题,简单记录如下:
-
输入访问路径,如 http://localhost:8080/swagger 后,页面请求的是登录首页
很显然这个是因为请求前未登录,没有携带可访问token,所以请求被拦截了,我们需要将swagger请求做放行处理,类似代码如下,重点步骤1和2:
public class ErpInterceptor implements Interceptor { @Override public void intercept(Invocation invocation) { try { Controller controller = invocation.getController(); //1.截取Swagger请求前缀 String url = controller.getRequest().getRequestURI(); String[] prefix = url.split("/"); //2.Swagger放行 if(!("swagger").equals(prefix[1])){ String token = BaseUtil.getToken(controller.getRequest()); AdminUser adminUser = RedisManager.getRedis().get(token); if (adminUser==null) { controller.renderJson(R.error(302, "请先登录!")); return; } BaseUtil.setUser(adminUser); //数据非空验证 if(!this.notNullValidate(invocation)){ return; } BaseUtil.userExpire(token); } //数据转换json的处理 this.modelToJson(invocation); invocation.invoke(); } catch (Exception e) { invocation.getController().renderJson(R.error("服务器响应异常")); Log.getLog(invocation.getController().getClass()).error("响应错误", e); } finally { BaseUtil.removeThreadLocal(); }
-
提示“Can not read response from server. Expected to read 4 bytes, read 0 bytes be”错误
当时这个问题让我纠缠了度娘一整个下午,找了各种集成方案,似乎没有发现与我遇到同样问题的伙伴,最终我猜测问题出在项目本身,而非集成Swagger的原因,如果出现这个问题,说明返回数据没有做json转换,而导致这个问题的原因是,我在处理Swagger放行的时候,将返回值转换json的处理漏掉了,导致集成Swagger后的数据没有转换成json,页面读取的时候就报错了!
-
其他问题
至于访问Swagger页面404什么的,基本是路径不对或者配置的细节问题,仔细查查问题应该不大
标题:Jfinal集成Swagger 极简配置
地址:http://blog.ivan.group/article/20
文章转载自:Ivan | 晏飞个人博客 [http://blog.ivan.group]