前言
提要
-
Springboot 集成swagger 通过springfox-swagger2实现SpringMVC的RESTful文档接口服务;
-
Springboot 集成 Jersey 通过swagger-jersey2-jaxrs 实现Jersey的文档接口服务;
环境
详细配置
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
|
<
properties
>
<
project.build.sourceEncoding
>UTF-8</
project.build.sourceEncoding
>
<
swagger.version
>1.5.12</
swagger.version
>
<
springfox-swagger2.version
>2.6.1</
springfox-swagger2.version
>
<
spring.boot.version
>1.5.1.RELEASE</
spring.boot.version
>
</
properties
>
<
repositories
>
<
repository
>
<
id
>spring-releases</
id
>
<
url
>https://repo.spring.io/libs-release</
url
>
</
repository
>
</
repositories
>
<
parent
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-parent</
artifactId
>
<
version
>1.5.1.RELEASE</
version
>
</
parent
>
<
dependencies
>
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-web</
artifactId
>
</
dependency
>
<!-- 支持自动确定版本路径: 写法由:link rel='stylesheet' href='/webjars/bootstrap/3.1.0/css/bootstrap.min.css'
变为: link rel='stylesheet' href='/webjars/bootstrap/css/bootstrap.min.css' -->
<
dependency
>
<
groupId
>org.webjars</
groupId
>
<
artifactId
>webjars-locator</
artifactId
>
<
version
>0.32</
version
>
<
exclusions
>
<
exclusion
>
<
groupId
>org.apache.commons</
groupId
>
<
artifactId
>commons-lang3</
artifactId
>
</
exclusion
>
</
exclusions
>
</
dependency
>
<!-- springboot 集成 jersey 、swagger 实现 JAX-RS Restful 開始 -->
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-jersey</
artifactId
>
</
dependency
>
<
dependency
>
<
groupId
>io.swagger</
groupId
>
<
artifactId
>swagger-jersey2-jaxrs</
artifactId
>
<
version
>${swagger.version}</
version
>
</
dependency
>
<!-- swagger 静态资源 -->
<
dependency
>
<
groupId
>org.webjars</
groupId
>
<
artifactId
>swagger-ui</
artifactId
>
<
version
>2.2.10</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.glassfish.hk2</
groupId
>
<
artifactId
>spring-bridge</
artifactId
>
<
version
>2.5.0-b34</
version
>
</
dependency
>
<!-- springboot 集成 jersey 、swagger 实现 JAX-RS Restful 結束 -->
<!-- springboot 集成 swagger 实现SpringMVC Restful 開始 -->
<!-- 解决 springfox-swagger 依赖swagger版本过低问题 -->
<
dependency
>
<
groupId
>io.swagger</
groupId
>
<
artifactId
>swagger-annotations</
artifactId
>
<
version
>${swagger.version}</
version
>
</
dependency
>
<
dependency
>
<
groupId
>io.swagger</
groupId
>
<
artifactId
>swagger-models</
artifactId
>
<
version
>${swagger.version}</
version
>
</
dependency
>
<
dependency
>
<
groupId
>io.springfox</
groupId
>
<
artifactId
>springfox-swagger2</
artifactId
>
<
version
>${springfox-swagger2.version}</
version
>
</
dependency
>
<
dependency
>
<
groupId
>io.springfox</
groupId
>
<
artifactId
>springfox-swagger-ui</
artifactId
>
<
version
>${springfox-swagger2.version}</
version
>
</
dependency
>
<!-- springboot 集成 swagger 实现SpringMVC Restful 結束 -->
<!-- Test -->
<
dependency
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-starter-test</
artifactId
>
<
scope
>test</
scope
>
</
dependency
>
</
dependencies
>
<
build
>
<
finalName
>${project.artifactId}</
finalName
>
<
plugins
>
<
plugin
>
<
groupId
>org.springframework.boot</
groupId
>
<
artifactId
>spring-boot-maven-plugin</
artifactId
>
<
version
>${spring.boot.version}</
version
>
<
configuration
>
<
mainClass
>sample.rs.service.SampleRestApplication</
mainClass
>
</
configuration
>
<
executions
>
<
execution
>
<
goals
>
<
goal
>repackage</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
build
>
|
1
2
|
server.servlet-path = /
spring.jersey.application-path = /api
|
1
2
3
4
5
6
7
8
9
10
|
import
org.springframework.boot.SpringApplication;
import
org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public
class
SampleRestApplication {
public
static
void
main(String[] args) {
SpringApplication.run(SampleRestApplication.
class
, args);
}
}
|
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
|
import
javax.annotation.PostConstruct;
import
org.glassfish.jersey.server.ResourceConfig;
import
org.glassfish.jersey.server.wadl.internal.WadlResource;
import
org.springframework.beans.factory.annotation.Value;
import
org.springframework.stereotype.Component;
import
io.swagger.jaxrs.config.BeanConfig;
import
io.swagger.jaxrs.listing.ApiListingResource;
import
io.swagger.jaxrs.listing.SwaggerSerializers;
import
sample.jersey.demo1.HelloResource;
import
sample.jersey.demo1.JerseyTest;
import
sample.jersey.demo2.Endpoint;
import
sample.jersey.demo2.ReverseEndpoint;
import
sample.jersey.demo3.HelloService;
@Component
public
class
JerseyConfig
extends
ResourceConfig {
@Value
(
"${spring.jersey.application-path}"
)
private
String apiPath;
public
JerseyConfig() {
register(Endpoint.
class
);
register(ReverseEndpoint.
class
);
this
.registerEndpoints();
}
@PostConstruct
public
void
init() {
// Register components where DI is needed
this
.configureSwagger();
}
private
void
registerEndpoints() {
this
.register(HelloResource.
class
);
this
.register(JerseyTest.
class
);
this
.register(HelloService.
class
);
// Access through /<Jersey's servlet path>/application.wadl
this
.register(WadlResource.
class
);
}
private
void
configureSwagger() {
// Available at localhost:port/swagger.json
this
.register(ApiListingResource.
class
);
this
.register(SwaggerSerializers.
class
);
BeanConfig config =
new
BeanConfig();
config.setConfigId(
"springboot-jersey-swagger-docker-example"
);
config.setTitle(
"Spring Boot + Jersey + Swagger + Docker Example"
);
config.setVersion(
"v1"
);
config.setContact(
"wzh"
);
config.setSchemes(
new
String[] {
"http"
,
"https"
});
config.setBasePath(
this
.apiPath);
config.setResourcePackage(
"sample.jersey"
);
config.setPrettyPrint(
true
);
config.setScan(
true
);
}
}
|
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
|
import
static
com.google.common.base.Predicates.or;
import
static
springfox.documentation.builders.PathSelectors.regex;
import
java.util.Arrays;
import
org.springframework.beans.factory.annotation.Value;
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
import
com.google.common.base.Predicate;
import
springfox.documentation.builders.ApiInfoBuilder;
import
springfox.documentation.builders.PathSelectors;
import
springfox.documentation.builders.RequestHandlerSelectors;
import
springfox.documentation.service.ApiInfo;
import
springfox.documentation.service.ApiKey;
import
springfox.documentation.service.SecurityScheme;
import
springfox.documentation.spi.DocumentationType;
import
springfox.documentation.spring.web.plugins.Docket;
import
springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* api doc -- springfox swagger configuration
*/
@Configuration
@EnableSwagger2
public
class
SwaggerConfig {
@Value
(
"${spring.jersey.application-path}"
)
private
String apiPath;
@Bean
public
SecurityScheme apiKey() {
return
new
ApiKey(
"access_token"
,
"accessToken"
,
"header"
);
}
@Bean
public
Docket apiConfig() {
return
new
Docket(DocumentationType.SWAGGER_2).groupName(
"controller"
)
// 调用apiInfo方法,创建一个ApiInfo实例,里面是展示在文档页面信息内容
.apiInfo(apiInfo()).select()
// 控制暴露出去的路径下的实例
// 如果某个接口不想暴露,可以使用以下注解
// @ApiIgnore 这样,该接口就不会暴露在 swagger2 的页面下
.apis(RequestHandlerSelectors.basePackage(
"sample.jersey.controller"
)).paths(PathSelectors.any())
.build().useDefaultResponseMessages(
false
).securitySchemes(Arrays.asList(apiKey()));
}
@Bean
public
Docket restConfig() {
return
new
Docket(DocumentationType.SWAGGER_2).groupName(
"jax-rs"
).apiInfo(restInfo()).forCodeGeneration(
true
)
.pathMapping(
"/"
).select().paths(paths())
// 过滤的接口
.build().useDefaultResponseMessages(
false
);
}
// 请求url匹配,支持and or,可以过滤筛选
private
Predicate<String> paths() {
return
or(regex(
"/test/.*"
), regex(
"/rest/.*"
));
//
}
private
ApiInfo apiInfo() {
return
new
ApiInfoBuilder().title(
"berheley service controller api "
)
// 大标题
.description(
"spring boot webservice 平台 API"
)
// 小标题
// .termsOfServiceUrl("http://ww.swagger.com/")
// .contact(new Contact("swagger", "www.swagger.com",
// "swagger@foxmail.com"))
.version(
"2.0"
).build();
}
private
ApiInfo restInfo() {
return
new
ApiInfoBuilder().title(
"berheley service rest api "
)
// 大标题
.description(
"spring boot webservice 平台 API"
)
// 小标题
.version(
"2.0"
).build();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package
sample.jersey.controller;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestMethod;
import
org.springframework.web.bind.annotation.RequestParam;
import
org.springframework.web.bind.annotation.ResponseBody;
import
io.swagger.annotations.ApiOperation;
import
io.swagger.annotations.ApiParam;
@Controller
@RequestMapping
(
"/test"
)
public
class
TestController {
@ResponseBody
@RequestMapping
(value =
"/show"
, method = RequestMethod.POST)
// 这里指定RequestMethod,如果不指定Swagger会把所有RequestMethod都输出,在实际应用中,具体指定请求类型也使接口更为严谨。
@ApiOperation
(value =
"测试接口"
, notes =
"测试接口详细描述"
)
public
String show(
@ApiParam
(required =
true
, name =
"name"
, value =
"姓名"
)
@RequestParam
(name =
"name"
) String stuName) {
return
"success"
;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package
sample.jersey.demo3;
import
javax.ws.rs.GET;
import
javax.ws.rs.Path;
import
javax.ws.rs.PathParam;
import
javax.ws.rs.Produces;
import
javax.ws.rs.core.MediaType;
import
org.springframework.stereotype.Service;
@Path
(
"/rest"
)
@Component
public
class
HelloService {
@GET
@Path
(
"/sayHello/{a}"
)
@Produces
(MediaType.TEXT_PLAIN)
public
String sayHello(
@PathParam
(
"a"
) String a) {
return
"Hello "
+ a +
", Welcome to CXF RS Spring Boot World!!!"
;
}
}
|
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
|
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
meta
http-equiv
=
"x-ua-compatible"
content
=
"IE=edge"
>
<
title
>Swagger UI</
title
>
<
link
rel
=
"icon"
type
=
"image/png"
href
=
"webjars/swagger-ui/images/favicon-32x32.png"
sizes
=
"32x32"
/>
<
link
rel
=
"icon"
type
=
"image/png"
href
=
"webjars/swagger-ui/images/favicon-16x16.png"
sizes
=
"16x16"
/>
<
link
href
=
'/webjars/swagger-ui/css/typography.css'
media
=
'screen'
rel
=
'stylesheet'
type
=
'text/css'
/>
<
link
href
=
'/webjars/swagger-ui/css/reset.css'
media
=
'screen'
rel
=
'stylesheet'
type
=
'text/css'
/>
<
link
href
=
'/webjars/swagger-ui/css/screen.css'
media
=
'screen'
rel
=
'stylesheet'
type
=
'text/css'
/>
<
link
href
=
'/webjars/swagger-ui/css/reset.css'
media
=
'print'
rel
=
'stylesheet'
type
=
'text/css'
/>
<
link
href
=
'/webjars/swagger-ui/css/print.css'
media
=
'print'
rel
=
'stylesheet'
type
=
'text/css'
/>
<
script
src
=
'/webjars/swagger-ui/lib/object-assign-pollyfill.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/jquery-1.8.0.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/jquery.slideto.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/jquery.wiggle.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/jquery.ba-bbq.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/handlebars-4.0.5.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/lodash.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/backbone-min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/swagger-ui.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/highlight.9.1.0.pack.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/highlight.9.1.0.pack_extended.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/jsoneditor.min.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/marked.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lib/swagger-oauth.js'
type
=
'text/javascript'
></
script
>
<!-- Some basic translations -->
<
script
src
=
'/webjars/swagger-ui/lang/translator.js'
type
=
'text/javascript'
></
script
>
<
script
src
=
'/webjars/swagger-ui/lang/zh-cn.js'
type
=
'text/javascript'
></
script
>
<
script
type
=
"text/javascript"
>
$(function () {
var url = window.location.search.match(/url=([^&]+)/);
if (url && url.length > 1) {
url = decodeURIComponent(url[1]);
} else {
url = "/api/swagger.json";
}
hljs.configure({
highlightSizeThreshold: 5000
});
// Pre load translate...
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi){
if(typeof initOAuth == "function") {
/* initOAuth({
clientId: "your-client-id",
clientSecret: "your-client-secret-if-required",
realm: "your-realms",
appName: "your-app-name",
scopeSeparator: " ",
additionalQueryStringParams: {}
}); */
}
if(window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
jsonEditor: false,
defaultModelRendering: 'schema',
showRequestHeaders: false,
showOperationIds: false
});
window.swaggerUi.load();
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
});
</
script
>
</
head
>
<
body
class
=
"swagger-section"
>
<
div
id
=
'header'
>
<
div
class
=
"swagger-ui-wrap"
>
<
a
id
=
"logo"
href
=
"http://swagger.io"
><
img
class
=
"logo__img"
alt
=
"swagger"
height
=
"30"
width
=
"30"
src
=
"/webjars/swagger-ui/images/logo_small.png"
/><
span
class
=
"logo__title"
>swagger</
span
></
a
>
<
form
id
=
'api_selector'
>
<
div
class
=
'input'
><
input
placeholder
=
"http://example.com/api"
id
=
"input_baseUrl"
name
=
"baseUrl"
type
=
"text"
/></
div
>
<
div
id
=
'auth_container'
></
div
>
<
div
class
=
'input'
><
a
id
=
"explore"
class
=
"header__btn"
href
=
"#"
data-sw-translate>Explore</
a
></
div
>
</
form
>
</
div
>
</
div
>
<
div
id
=
"message-bar"
class
=
"swagger-ui-wrap"
data-sw-translate> </
div
>
<
div
id
=
"swagger-ui-container"
class
=
"swagger-ui-wrap"
></
div
>
</
body
>
</
html
>
|