-
Swagger与SpringMVC项目整合
为了方便的管理项目中API接口,在网上找了好多关于API接口管理的资料,感觉目前最流行的莫过于Swagger了,功能强大,UI界面漂亮,并且支持在线测试等等,所以本人仔细研究了下Swagger的使用,下面就如何将Swagger与个人的SpringMVC项目进行整合做详细说明:
最终API管理界面:
详细步骤:
Step1:项目中引入相关jar包:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <version.spring>3.2.9.RELEASE</version.spring> <version.jackson>2.4.4</version.jackson> </properties> <dependencies> .... <dependency> <groupId>com.mangofactory</groupId> <artifactId>swagger-springmvc</artifactId> <version>0.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${version.jackson}</version> </dependency> </dependencies>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
Step2:添加自定义config文件
package com.spg.apidoc.common.configer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.mangofactory.swagger.configuration.SpringSwaggerConfig; import com.mangofactory.swagger.models.dto.ApiInfo; import com.mangofactory.swagger.plugin.EnableSwagger; import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin; /** * 项目名称:apidoc * * @description: * @author Wind-spg * @create_time:2015年2月10日 上午10:27:51 * @version V1.0.0 * */ @Configuration @EnableSwagger // Loads the spring beans required by the framework public class MySwaggerConfig { private SpringSwaggerConfig springSwaggerConfig; /** * Required to autowire SpringSwaggerConfig */ @Autowired public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) { this.springSwaggerConfig = springSwaggerConfig; } /** * Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc * framework - allowing for multiple swagger groups i.e. same code base * multiple swagger resource listings. */ @Bean public SwaggerSpringMvcPlugin customImplementation() { return new SwaggerSpringMvcPlugin(this.springSwaggerConfig).apiInfo(apiInfo()).includePatterns( ".*?"); } private ApiInfo apiInfo() { ApiInfo apiInfo = new ApiInfo( "My Apps API Title", "My Apps API Description", "My Apps API terms of service", "My Apps API Contact Email", "My Apps API Licence Type", "My Apps API License URL"); return apiInfo; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
Step3:将此配置加入到Spring容器中,如下:
<bean class="com.spg.apidoc.common.configer.MySwaggerConfig" />
- 1
Step4:在代码中添加相关APIAnnotation,如下:
@ResponseBody @RequestMapping( value = "addUser", method = RequestMethod.POST, produces = "application/json; charset=utf-8") @ApiOperation(value = "添加用户", httpMethod = "POST", response = BaseResultVo.class, notes = "add user") public String addUser(@ApiParam(required = true, name = "postData", value = "用户信息json数据") @RequestParam( value = "postData") String postData, HttpServletRequest request) { LOGGER.debug(String.format("at function, %s", postData)); if (null == postData || postData.isEmpty()) { return super.buildFailedResultInfo(-1, "post data is empty!"); } UserInfo user = JSON.parseObject(postData, UserInfo.class); int result = userService.addUser(user); return buildSuccessResultInfo(result); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
说明:
其中@ApiOperation和@ApiParam为添加的API相关注解,个参数说明如下:
@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response = “接口返回参数类型”, notes = “接口发布说明”;其他参数可参考源码;
@ApiParam(required = “是否必须参数”, name = “参数名称”, value = “参数具体描述”Step5:添加Swagger UI配置
在GitHub上下载SwaggerUI项目,将dist下所有内容拷贝到本地项目webapp下面,结果目录如下图所示:
Step6:修改index.html
将index.html中http://petstore.swagger.wordnik.com/v2/swagger.json修改为http://localhost:8080/{projectname}/api-docs
到此为止,所有配置完成,启动你的项目,访问http://localhost:8080/{projectName}/index.html即可看到如下所示页面:
项目最终demo可见个人GitHub
https://github.com/itboyspg/spg-code/tree/master/apidoc
参考:
https://github.com/martypitt/swagger-springmvc
https://github.com/swagger-api/swagger-ui
http://blog.csdn.net/fengspg/article/details/43705537
当我们把我们的服务以REST的形式接口暴露出去,其他开发者要调用我们的接口首先要能够详细的了解我们的API,目前几乎所有的开放平台都是把API以文档的形式放在网站上,例如:新浪、淘宝、微信等等。
在开发者调用API之前对一些API说明的理解比较模糊,总想着能直接验证一下自己的理解就好了,而不是需要去项目写测试代码来验证自己的想法。即API文档应具备直接执行能力。Swagger就是这样的一个利器,Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
下面说一下如何为现有项目添加Swagger
首先添加对Swagger的依赖
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-core_2.10</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.10.0</version>
</dependency>
加入对Swagger的配置类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.plugin.EnableSwagger;
import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;
import com.wordnik.swagger.model.ApiInfo;
@Configuration
@EnableSwagger
public class MySwaggerConfig {
private SpringSwaggerConfig springSwaggerConfig;
/**
* Required to autowire SpringSwaggerConfig
*/
@Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
this.springSwaggerConfig = springSwaggerConfig;
}
/**
* Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc framework - allowing for multiple
* swagger groups i.e. same code base multiple swagger resource listings.
*/
@Bean
public SwaggerSpringMvcPlugin customImplementation(){
SwaggerSpringMvcPlugin ssmp = new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
.apiInfo(apiInfo())
.swaggerGroup("api-docs").build();
return ssmp;
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"tk API SPECIFICATION",
"This is the tk api specification,here you can dig into the details of api and do api testing as well.",
"",
"",
"",
"");
return apiInfo;
}
}
在application.xml中增加配置:
<mvc:annotation-driven/>
<bean id="apiDoc" class="com.tk.framework.rest.framework.swaggerconfig.MySwaggerConfig"/>
<!-- Enable scanning of spring @Configuration classes -->
<context:annotation-config/>
<!-- Enable the default documentation controller-->
<context:component-scan base-package="com.mangofactory.swagger.controllers"/>
<!-- Pick up the bundled spring config-->
<context:component-scan base-package="com.mangofactory.swagger.configuration"/>
接着,给开放API的Resource类加上API Annotation,这样上一步配置的Scanner就能够扫描到该Resource开放的API了。
@RestController
@RequestMapping(value = "/1/users")
@Api(value = "User", description = "User service api", position = 1)
public class UserResourceV1 extends BaseResources
{
private static final Logger logger = LoggerFactory.getLogger(UserResourceV1.class);
@Autowired
private UserService userService;
@ResourceDescription(Resource="user", Operation="getUser")
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ApiOperation(httpMethod = "GET", nickname="getUser", value = "get user by userId")
public ResponseModel getUser(@ApiParam(value = "id for greeting", required = true)@PathVariable String id) throws RestException
{
UserModel u = null;
try
{
u = userService.findById(id);
}
catch (Exception e)
{
logger.error(e.getMessage());
throw new RestException(e.getMessage());
}
ResponseModel r = new ResponseModel();
r.setStatus(200);
r.setResult(u);
return r;
}
}
为Model添加Swagger的Annotation,这样Swagger Scanner可以获取更多关于Model对象的信息。 :
@ApiModel(value="User")
@Entity
@Table(name = "user")
public class UserModel {
/**
* id
*/
@ApiModelProperty(required = true)
private String id;
/**
* 姓名
*/
@ApiModelProperty(required = true)
private String name;
/**
* 年龄
*/
@ApiModelProperty(required = true, allowableValues="range[1,100]")
private Integer age;
/**
* 性别
*/
@ApiModelProperty(required = true, allowableValues = "F,M")
private String sex;
@ApiModelProperty(required = true)
private String password;
……
在Swagger Annotation中:
@API表示一个开放的API,可以通过description简要描述该API的功能。
在一个@API下,可有多个@ApiOperation,表示针对该API的CRUD操作。在ApiOperation Annotation中可以通过value,notes描述该操作的作用,response描述正常情况下该请求的返回对象类型。
在一个ApiOperation下,可以通过ApiResponses描述该API操作可能出现的异常情况。
@ApiParam用于描述该API操作接受的参数类型
接下来,我们把这些信息和Swagger UI集成,以非常美观,实用的方式把这些API信息展示出来。
首先,从github(https://github.com/wordnik/swagger-ui)上下载Swagger-UI, 把该项目dist目录下的内容拷贝到项目的webapp的目录下。
然后,修改index.jsp, 把Swagger UI对象中的URL替换为自己的API路径:
window.swaggerUi = new SwaggerUi({
url: "/api/api-docs",
dom_id: "swagger-ui-container",
启动项目,最后如下图所示:
具有直接测试API的能力:
http://blog.163.com/xh_ding/blog/static/193903289201411592759809/