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

项目jar包下载:http://download.csdn.net/detail/fengspg/8550451

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/
 

RESTful风格的Web服务框架:Swagger的更多相关文章

  1. Rest(Restful)风格的Web API跟RPC风格的SOAP WebService--这些名词都啥意思?

    经常看到这些词汇,也有baidu或google过,但记忆里总是模糊,不确定,以至于别人问及的时候,总说不清楚.开篇随笔记录下.大家有补充或者意见的尽请留文. 本文顺序: 一.Rest(Restful) ...

  2. 构建RESTful风格的WCF服务

    构建RESTful风格的WCF服务 RESTful Wcf是一种基于Http协议的服务架构风格. 相较 WCF.WebService 使用 SOAP.WSDL.WS-* 而言,几乎所有的语言和网络平台 ...

  3. "轻"量级 Java Web 服务框架漫谈

    博文太长了, 还是先说下概要: 框架"轻量"与否可以从两方面来看待: 1) 框架本身的体量 - 例如小 jar 无依赖的苗条框架; 2) 用户使用框架是否获得各种便利而无阻隔(&q ...

  4. 在 Docker 上运行一个 RESTful 风格的微服务

    tags: Microservice Restful Docker Author: Andy Ai Weibo:NinetyH GitHub: https://github.com/aiyanbo/d ...

  5. 记录一个调试REST风格的web服务的client

    coogle浏览器的advanced rest client很好用,记录一下,脑子不好,容易忘,,可以在chrome 的网上应用店添加 Rest client是用来调试REST风格的Web服务,接收P ...

  6. [收藏转贴]构建RESTful风格的WCF服务

    RESTful Wcf是一种基于Http协议的服务架构风格. 相较 WCF.WebService 使用 SOAP.WSDL.WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求. RESTf ...

  7. 通过 Jersey Http请求头,Http响应头,客户端 API 调用 REST 风格的 Web 服务

    原地址:http://blog.csdn.net/li575098618/article/details/47853263 Jersey 1.0 是一个开源的.可以用于生产环境的 JAX-RS(RES ...

  8. Jersey客户端API调用REST风格的Web服务

    Jersey 客户端 API 基础 jersey-1.14.jar 密码: cxug 要开始使用 Jersey 客户端 API,你首先需要创建一个 com.sun.jersey .api.client ...

  9. 基于cxf开发restful风格的Web Service

    一.写在前面 webservice一些简单的其他用法和概念,就不在这里赘述了,相信大家都可以在网上查到,我也是一个新手,写这篇文章的目的一方面是想记录自己成长的历程,另一方面是因为学习这个的时候花了点 ...

随机推荐

  1. 上传jar包到nexus私服

    摘要 通过网页和maven两种方式,上传本地的jar到nexus私服,以及引用jar时,自动引用依赖 1通过网页上传 这种方法只是上传了jar包.通过maven引用当前jar,不能取得jar的依赖   ...

  2. SQL给字段加上统一的某个字符

    表名:News  字段名:No_id Update News set No_id='字符'+No_id

  3. .net+easyui系列--验证框

    1.允许从 0 到 10个字符 <input id="vv" class="easyui-validatebox" data-options=" ...

  4. 用bootstrap的tab插件做一个图层切换效果(感觉会误导淫们,大家当乐子看吧)

    小伙伴们啊,我JS真的是个渣渣,所以总想要偷懒,于是为了实现效果就把tab插件给改了(各位大神轻拍啊,我是小白,很纯洁滴,小心脏也很脆弱)…… 最近做的项目为了考虑以后的移动设备兼容性,所以用了Boo ...

  5. javascript 定时器使用

    定时器的使用场合 setInterval() 方法,按照指定的周期(以毫秒记)来调用函数或计算表达式setInterval() 方法会不停的调用函数,知道 clearInterval() 被调用或窗口 ...

  6. IPX/SPX

    转自百度百科 方便阅读 IPX/SPX   目 录 1英文原义 2中文释义 3IPX协议 3.1 说明 3.2 应用 4SPX协议 4.1 说明 4.2 应用     1英文原义 IPX/SPX 2中 ...

  7. Delphi 类方法和普通方法的区别 .

    //类声明  TMyClass = class  public    class procedure MyProc;  //类方式    constructor Create;      //Crea ...

  8. oc 获取当前时间

    //获取当前日期 NSDate* date = [NSDate date]; NSDateFormatter* dateFormat = [[NSDateFormatter alloc] init]; ...

  9. 【工具篇】source Insight

    不多说,阅读代码利器. 一.修改背景颜色 使用淡绿色更护眼(听说而已),菜单“选项”>>“属性”,使用自己喜欢的颜色吧.我的淡绿色RGB是181,236,207 二.行号,空格替换tabs ...

  10. 简单的完全背包HDU1114

    今天广州下雨啦,不过没关系啦,反正我最近也都在刷题学习算法. 昨天做了五题01背包,今天还是背包,不过是完全背包,估计做动态规划要持续好一段时间,一开始选了一道简单题目啦. HDU1114,看了小一段 ...