Swagger框架学习分享

一、背景介绍

1.1.项目简介

Swagger项目是由Dilip Krishnan和Adrian Kelly等人维护开发的一个为Spring Web MVC 项目提供方法文档的一个框架。该框架最主要的功能是将Controller的方法进行可视化的展现,像方法注释,方法参数,方法返回值等都提供了相应的用户界面,尤其是对JSON参数的支持。同时可以结合swagger-ui可以对用户界面进行不同程度的定制,也可以对方法进行一个简单的测试。

1.2.code repository

github:https://github.com/springdox/springdox
maven:http://www.mvnrepository.com/artifact/com.mangofactory/swagger-springmvc

1.3.演示项目

官方:https://github.com/adrianbk/swagger-springmvc-demo
民间:https://github.com/qq291462491/bugkillers

二、开发准备

2.1.环境准备

idea intellij 13+
Oracle java 1.6
Gradle 2.0 +

2.2.项目搭建

2.2.1.jar仓库

Maven

1
2
3
4
5
6
7
8
9
10
11
12
13
<repositories>
<repository>
<id>jcenter-release</id>
<name>jcenter</name>
<url>http://oss.jfrog.org/artifactory/oss-release-local/</url>
</repository>
</repositories>

<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>1.0.0</version>
</dependency>

Gradle

1
2
3
4
5
repositories {
jcenter()
}

compile "com.mangofactory:swagger-springmvc:1.0.0"
2.2.2.相关依赖
1
2
3
Spring 3.2.x or above
jackson 2.4.4
guava 15.0
2.2.3.编写配置文件

编写一个Java文件,并使用注解:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
@Configuration 配置注解,自动在本类上下文加载一些环境变量信息
@EnableWebMvc
@EnableSwagger 使swagger生效
@ComponentScan("com.myapp.packages") 需要扫描的包路径
示例:
package org.bugkillers.back.swagger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.models.dto.ApiInfo;
import com.mangofactory.swagger.paths.SwaggerPathProvider;
import com.mangofactory.swagger.plugin.EnableSwagger;
import com.mangofactory.swagger.plugin.SwaggerSpringMvcPlugin;
/**
* 使用注解的方式来扫描API
* 无需在Spring的xml配置文件来配置,由 @see @EnableWebMvc 代替
* <p/>
* <p> @author 刘新宇
*
* <p> @date 2015年1月30日 下午1:18:48
* <p> @version 0.0.1
*/

@Configuration
@EnableWebMvc
@EnableSwagger
@ComponentScan(basePackages ={"com.ak.swaggerspringmvc.shared.controller", "com.ak.spring3.music"})
public class CustomJavaPluginConfig extends WebMvcConfigurerAdapter {
private SpringSwaggerConfig springSwaggerConfig;
@Autowired
public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
this.springSwaggerConfig = springSwaggerConfig;
}
/**
* 链式编程 来定制API样式
* 后续会加上分组信息
* @return
*/

@Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
.apiInfo(apiInfo())
.includePatterns(".*")
// .pathProvider(new GtPaths())
.apiVersion("0.0.1")
.swaggerGroup("user");
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo(
"bugkillers-back API",
"bugkillers 后台API文档",
"<a href="http://127.0.0.1:9081/api" "="" style="color: rgb(59, 115, 175); text-decoration: none; border-radius: 0px !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; min-height: inherit !important; background: none !important;">http://127.0.0.1:9081/api",
"bugkillers@163.com",
"My License",
"My Apps API License URL"
);
return apiInfo;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}

class GtPaths extends SwaggerPathProvider{
@Override
protected String applicationPath() {
return "/restapi";
}
@Override
protected String getDocumentationPath() {
return "/restapi";
}
}

}

也可以自己不写配置类,直接使用默认的实现类,在Spring的配置文件中共配置:(不推荐)

1
2
<mvc:annotation-driven/> <!-- Required so swagger-springmvc can access spring's RequestMappingHandlerMapping  -->
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />

2.2.4.与swagger-ui集成

方式一:

1
2
3
4
Note: Only use this option if you don't need to customize any of the swagger-ui static content, otherwise use option 2.
Use the web-jar which packages all of the swagger-ui static content.
Requires that your app is using the servlet 3 specification.
For non-spring boot applications some extra spring configuration (ResourceHandler's) is required. See: https://github.com/adrianbk/swagger-springmvc-demo/tree/master/swagger-ui

1
2
3
4
dependencies {
...
compile "org.ajar:swagger-spring-mvc-ui:0.4"
}

方式二:(推荐)

1
2
3
4
Manually copy all of the static content swagger-ui's dist directory (https://github.com/wordnik/swagger-ui/tree/master/dist)
Provide the necessary view resolvers and resource handlers to serve the static content.
Consult the spring documentation on serving static resources.
The following is one way to serve static content from /src/main/webapp

1
2
3
4
<!-- Direct static mappings -->
<mvc:resources mapping="*.html" location="/"/>
<!-- Serve static content-->
<mvc:default-servlet-handler/

2.6.5.Controller配置

使用注解对Controller进行配置:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@Api 配置方法API
@ApiOperation API的操作 GET PUT DELETE POST
@ApiParam API的方法参数描述
示例Controller
package org.bugkillers.back.user.controller;
import java.util.List;
import org.bugkillers.back.bean.User;
import org.bugkillers.back.result.Result;
import org.bugkillers.back.user.service.UserService;
import org.bugkillers.back.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
/**
* 用户操作Controller
* <p/>
* <p>
*
* @author 刘新宇
*
* <p>
* @date 2015130日 上午10:50:34
* <p>
* @version 0.0.1
*/
@Api(value = "user-api", description = "有关于用户的CURD操作", position = 5)
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService service;
/**
* 注册用户
* @param user
*/
@ApiOperation(value = "注册", notes = "注册用户", position = 3)
@ResponseBody
@RequestMapping(value = { "/regist" }, method = RequestMethod.POST)
public ResponseEntity<?> regist(@RequestBody User user) {
service.save(user);
Result<String> result = ResultUtil.buildSuccessResult("注册成功");
return new ResponseEntity<Result<String>>(result, HttpStatus.OK);
}

/**
* 根据pk查找用户
* @param userPk
* @return
*/
@ApiOperation(value = "根据pk查找用户", notes = "返回用户实体对象", response = User.class, position = 2)
@ResponseBody
@RequestMapping(value = { "/{userPk}" }, method = RequestMethod.GET)
public ResponseEntity<?> findByPk(
@ApiParam(value = "填写Pk", allowableValues = "range[1,5]", required = true, defaultValue = "userPk", allowMultiple = true) @PathVariable("userPk") Integer userPk) {
Result<User> result = ResultUtil.buildSuccessResult(service.findByPk(userPk));
return new ResponseEntity<Result<User>>(result, HttpStatus.OK);
}

/**
* 测试
* @param who
* @return
*/
@ApiOperation(value = "Hellow World", notes = "测试功能", position = 1)
@ResponseBody
@RequestMapping(value = { "/hello/{who}" }, method = RequestMethod.GET)
public ResponseEntity<?> hello(
@ApiParam(value = "填写名称") @PathVariable("who") String who) {
Result<String> result = ResultUtil.buildSuccessResult( "Hello guys" + " " + who + "!");
return new ResponseEntity<Result<String>>(result, HttpStatus.OK);
}
/**
* 查询所有
* @return
*/
@ApiOperation(value = "获取所有用户", notes = "返回用户实体对象集合", position = 5)
@RequestMapping(value = "/findAll", method = RequestMethod.GET)
public @ResponseBody ResponseEntity<?> findAll() {
Result<List<User>> result = ResultUtil.buildSuccessResult( service.findAll());
return new ResponseEntity<Result<List<User>>>(result, HttpStatus.OK);
}

/**
* 根据用户pk更新实体
* @param userPk 用户pk
* @param user 返回更新后的实体
* @return
*/
@ApiOperation(value = "更新用户", notes = "返回更新的用户实体对象",position = 5)
@RequestMapping(value = "/update/{userPk}", method = RequestMethod.PUT)
public ResponseEntity<?> updateByPk(
@PathVariable("userPk") Integer userPk, @RequestBody User user) {
user.setPk_user(userPk);
service.update(user);
Result<User> result = ResultUtil.buildSuccessResult(user);
return new ResponseEntity<Result<User>>(result, HttpStatus.OK);
}

/**
* 根据用户pk删除实体
* @param userPk 用户pk
* @return
*/
@ApiOperation(value = "删除用户", notes = "根据pk删除用户",position = 5)
@RequestMapping(value = "/delete/{userPk}", method = RequestMethod.GET)
public ResponseEntity<?> deleteByPk(
@PathVariable("userPk") Integer userPk) {
service.delete(userPk);
Result<String> result = ResultUtil.buildSuccessResult("删除成功");
return new ResponseEntity<Result<String>>(result, HttpStatus.OK);
}
}

2.2.6.启动中间件

项目配置了Jetty或者Tomcat等Web容器的话,在对应的Controller配置好的话就可以启动看效果了。
访问本机:http://127.0.0.1:9081/api
远程示例:http://115.29.170.213/api

2.2.7.需求定制

分组信息定制
Url定制
Http相应定制

三、学习感想

Swagger很好的为我们在开发RESTful框架应用时,前后台分离的情况下提供了很有效的解决方案,上手迅速,操作简单,界面精简,功能完善,满足各种定制化的需求,是在使用Spring MVC做Web开发时的不二选择。通过对swagger的学习,增强了英语交流的能力,改变了以前的学习方法,收获了很多,同时也也得感谢国外友人的悉心帮助~技术无国界~

3.1 Guava工具类的使用 http://ifeve.com/google-guava/

Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等

3.2 Gradle构建工具的使用 http://ifeve.com/google-guava/

配置更加简洁,支持Maven,好多开源项目已经从Maven转到Gradle。

3.3 Groovy语言 http://groovy.codehaus.org/User+Guide

和scala、clojure等同是在JVM上运行的脚本语言,丰富的类库,和Java互通,可以作为Java程序员的第二语言。

3.4 链式编程 (return this)

Java中类似Swagger配置文件SwaggerSpringMvcPlugin
JQuery中类似 $(“#p1”).css(“color”,”red”).slideUp(2000).slideDown(2000);

在公司的Wiki上写的博文,因为外面访问不了公司的内网,故贴过来给需要的小伙伴们分享一下,有疑问的可以随时交流。