Spring MVC 中使用 Swagger2 构建动态 RESTful API
当多终端(WEB/移动端)需要公用业务逻辑时,一般会构建 RESTful 风格的服务提供给多终端使用。
为了减少与对应终端开发团队频繁沟通成本,刚开始我们会创建一份 RESTful API 文档来记录所有接口细节。
但随着项目推进,这样做所暴露出来的问题也越来越严重。
a. 接口众多,细节复杂(需考虑不同的 HTTP 请求类型、HTTP 头部信息、HTTP 请求内容..),高质量地创建这份文档本身就是件非常吃力的事。
b. 不断修改接口实现必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
基于此,项目组在早些时间引入了 Swagger,经过几个项目的沉淀,确实起到了很不错的效果。
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
服务的方法、参数、模型紧密集成到服务器端的代码,让维护文档和调整代码融为一体,使 API 始终保持同步。
本文主要描述 Swagger 与 SpringMVC 的集成过程以及遇到的一些问题,权当抛砖引玉只用,具体项目具体分析。

1. Maven 依赖和最简配置
<!--restfull APi swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency> <dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
Spring-Context Swagger 配置:
<!-- swagger2 配置类-->
<bean id="config" class="com.rambo.spm.core.config.SwaggerConfig"/> <!-- swagger2 静态资源交由 spring 管理映射(springfox-swagger-ui.jar 为静态资源包)-->
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
<mvc:resources /> 由 Spring MVC 处理静态资源,并添加一些有用的附加值功能。
a. <mvc:resources /> 允许静态资源放在任何地方,如 WEB-INF 目录下、类路径下等,完全打破了静态资源只能放在 Web 容器的根路径下这个限制。
b.<mvc:resources /> 依据当前著名的 Page Speed、YSlow 等浏览器优化原则对静态资源提供优化。
SwaggerConfig 配置类:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder();
apiInfoBuilder.title("SPM Doc");
apiInfoBuilder.description("SPM Api文档");
apiInfoBuilder.contact(new Contact("orson", "https://www.cnblogs.com/", ""));
apiInfoBuilder.version("2.0");
return apiInfoBuilder.build();
}
}
对于生成哪些请求方法 API ? Swagger 提供了 RequestHandlerSelectors 对象的以下方法进行限制范围:

2. 服务注解配置实践
经过上述的操作,其实 Swagger 已经集成完毕,在项目开发推进中,只需在对应 RESTful 服务上添加对应注解即可。
@Api:注解在类上,说明该类的作用。可以标记一个 Controller 类做为 swagger 文档资源,使用方式:
@Api(description = "用户管理")
@ApiOperation:注解在方法上,说明方法的作用,每一个url资源的定义,使用方式:
@ApiOperation(value = "获取所有用户列表")
@ApiParam、@ApiImplicitParam:注解到参数上,说明该参数作用,使用方式:
@ApiParam(value = "用户ID") String userId
上述都为最简配置,构建清晰的 API 文档已足够,当然还有很丰富的注解,知道有就行了。
@RestController
@Api(description = "用户管理")
public class UserRestController extends BaseController {
@Autowired
private SysUserService sysUserService; @GetMapping("r/user/get")
@ApiOperation(value = "获取特定用户详情")
public Object getUser(ModelMap modelMap, @ApiParam(value = "用户ID") String userId) { } @PostMapping("r/user/add")
@ApiOperation(value = "添加用户")
public Object addUser(ModelMap modelMap, @ModelAttribute @Valid SysUser user, BindingResult result) { }
}
在项目后续使用中遇到的一些问题:
a. 一些方法入参如 HttpServletRequest、HttpServletResponse、HttpSession、ModelMap 等等,这些参数在生成 API 文档时是无意义的,Swagger 正确的配置方式?
刚开始时使用 @ApiParam(hidden = true) 注解这些参数,方法繁多的时候,这些类型的入参都要写一遍,使用起来很冗余。
在 API 中发现 Docket 对象有 ignoredParameterTypes 方法,在配置类中统一定义忽略的参数类型即可,这样就方便很多。
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.ignoredParameterTypes(ModelMap.class, HttpServletRequest.class,HttpServletResponse.class, BindingResult.class)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build();
}
b. 当请求的参数为封装的对象时,怎样进行注解?对象中的属性怎样注解?怎样屏蔽对象中的莫个属性?
请求的参数为对象时,使用Spring @ModelAttribute 注解对应对象,对象当中的属性使用 @ApiModelProperty ,屏蔽莫个属性 @ApiModelProperty(hidden = true)
@ApiModelProperty(hidden = true)
private String uuid; @ApiModelProperty("姓名")
private String name; @ApiModelProperty("密码")
private String passwd;

c. @Api 注解中的 tags 值不支持中文,中文值会导致无法展开;
Swagger 有很丰富的工具,还能做很多事,本文所述只是能让你迅速了解它、使用它、有需要多查资料、多翻博客。
Spring MVC 中使用 Swagger2 构建动态 RESTful API的更多相关文章
- Spring MVC中使用 Swagger2 构建Restful API
1.Spring MVC配置文件中的配置 [java] view plain copy <!-- 设置使用注解的类所在的jar包,只加载controller类 --> <contex ...
- Spring Boot中使用Swagger2构建强大的RESTful API文档
由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这 ...
- Spring Boot中使用Swagger2构建RESTful API文档
在开发rest api的时候,为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题: 1.由于接口众多,并且细 ...
- Spring Boot 中使用 Swagger2 构建强大的 RESTful API 文档
项目现状:由于前后端分离,没有很好的前后端合作工具. 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型.HTTP头部信息.HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下 ...
- Spring Boot中使用Swagger2构建RESTful APIs
关于 Swagger Swagger能成为最受欢迎的REST APIs文档生成工具之一,有以下几个原因: Swagger 可以生成一个具有互动性的API控制台,开发者可以用来快速学习和尝试API. S ...
- Spring Boot中使用Swagger2构建RESTful APIs介绍
1.添加相关依赖 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <depen ...
- Spring Boot中使用Swagger2构建API文档
程序员都很希望别人能写技术文档,自己却很不愿意写文档.因为接口数量繁多,并且充满业务细节,写文档需要花大量的时间去处理格式排版,代码修改后还需要同步修改文档,经常因为项目时间紧等原因导致文档滞后于代码 ...
- Spring Boot中使用Swagger2构建强大的RESTful(最新全,无坑)
1:说明 网上这类文章 太多, 一搜一大把 ,但是要不是知识太过于老旧,就是配置没有说名清楚,你的项目按照他的配置却不能正常运行: 所以本文的目的: 配置swagger 2 那swagger 1 不 ...
- Spring Boot中使用Swagger2自动构建API文档
由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这 ...
随机推荐
- JavaWeb(二)jsp运行原理,九大内置对象
JSP运行原理: 每个JSP页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ...
- CSS选择器大汇总
CSS选择器是学习CSS以及Web编程的基础. 整理出常用的CSS选择器,供自己和大家一起学习. 基本选择器 * /*通用元素选择器,匹配页面任何元素(这也就决定了我们很少使用)*/ #id /*id ...
- Java 环境设置
Java 环境设置 本地环境设置 如果你依然想要为 Java 编程语言设置环境,那么本节将指导你如何在你的电脑上下载和设置 Java.请按照以下步骤进行环境设置. Java SE 可以从下载 Java ...
- Android笔记: 播放提示音 的简单方法
public static void sendSound(Context mContext) { //上下文 Uri mUri= RingtoneManager.getDefaultUri(Ringt ...
- pickle模块的使用python3
Python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...
- 【.net 深呼吸】实时获取计算结果
上次老周介绍了在 UWP 应用中通过 x:Bind 标记来绑定到方法,以实现实时获取计算结果.今天,咱们来耍耍WPF上面的实现方法. 虽然,WPF 没有 x:Bind 标记(暂时没有,以后不好说),但 ...
- Django创建博客
拜读http://www.cnblogs.com/fnng/p/3737964.html 后自操作步骤,mark一下 我的想法: modles.py中只负责添加类,定义数据结构,至于将该类添加到adm ...
- Ext.grid.EditorGridPanel点击单元格添加菜单栏
1.定义菜单栏需要的全局变量 var khbm; var type; 2.新建一个菜单栏 var smenu = new Ext.menu.Menu({ id:"sMenu", i ...
- 常用bash命令
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "Helvetica Neue"; color: #454545 } p. ...
- 实战案例--TEMPDB暴涨
前言 tempdb暴增,造成磁盘空间不足,甚至影响业务运行. 正文 如图,tempdb log文件从7.40开始突然暴涨,因为 tempdb 0 M到 40G tempdb 所 ...