Skip to content

Commit 7f68606

Browse files
author
程序猿DD-翟永超
authored
Merge pull request #57 from SpringForAll/1.6.0
1.6.0
2 parents cd6d750 + 44b58d5 commit 7f68606

File tree

4 files changed

+272
-21
lines changed

4 files changed

+272
-21
lines changed

README.md

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- 码云:https://gitee.com/didispace/spring-boot-starter-swagger
1010
- 使用样例:https://github.com/dyc87112/swagger-starter-demo
1111
- 我的博客:http://blog.didispace.com
12-
- 我们社区:http://spring4all.com
12+
- 我们社区:http://www.spring4all.com
1313

1414
**小工具一枚,欢迎使用和Star支持,如使用过程中碰到问题,可以提出Issue,我会尽力完善该Starter**
1515

@@ -27,11 +27,13 @@
2727
```xml
2828
<dependency>
2929
<groupId>com.spring4all</groupId>
30-
<artifactId>spring-boot-starter-swagger</artifactId>
31-
<version>1.5.1.RELEASE</version>
30+
<artifactId>swagger-spring-boot-starter</artifactId>
31+
<version>1.6.0.RELEASE</version>
3232
</dependency>
3333
```
3434

35+
**注意:从`1.6.0`开始,我们按Spring Boot官方建议修改了artifactId为`swagger-spring-boot-starter`,1.6.0之前的版本不做修改,依然为使用`spring-boot-starter-swagger` !**
36+
3537
- 在应用主类中增加`@EnableSwagger2Doc`注解
3638

3739
```java
@@ -80,13 +82,24 @@ swagger.globalOperationParameters[1].description=some description two
8082
swagger.globalOperationParameters[1].modelRef=string
8183
swagger.globalOperationParameters[1].parameterType=body
8284
swagger.globalOperationParameters[1].required=false
85+
86+
// 取消使用默认预定义的响应消息,并使用自定义响应消息
87+
swagger.apply-default-response-messages=false
88+
swagger.global-response-message.get[0].code=401
89+
swagger.global-response-message.get[0].message=401get
90+
swagger.global-response-message.get[1].code=500
91+
swagger.global-response-message.get[1].message=500get
92+
swagger.global-response-message.get[1].modelRef=ERROR
93+
swagger.global-response-message.post[0].code=500
94+
swagger.global-response-message.post[0].message=500post
95+
swagger.global-response-message.post[0].modelRef=ERROR
8396
```
8497

8598
## 配置说明
8699

87100
### 默认配置
88101

89-
```
102+
```properties
90103
- swagger.enabled=是否启用swagger,默认:true
91104
- swagger.title=标题
92105
- swagger.description=描述
@@ -142,7 +155,7 @@ swagger.exclude-path=/ops/**, /error
142155

143156
具体配置内容如下:
144157

145-
```
158+
```properties
146159
- swagger.docket.<name>.title=标题
147160
- swagger.docket.<name>.description=描述
148161
- swagger.docket.<name>.version=版本
@@ -190,7 +203,7 @@ swagger.docket.bbb.basePackage=com.yonghui
190203

191204
说明:默认配置与分组配置可以一起使用。在分组配置中没有配置的内容将使用默认配置替代,所以默认配置可以作为分组配置公共部分属性的配置。`swagger.docket.aaa.globalOperationParameters[0].name`会覆盖同名的全局配置。
192205

193-
### JSR-303校验注解支持
206+
### JSR-303校验注解支持(1.5.0 + 支持)
194207

195208
支持对JSR-303校验注解的展示,如下图所示:
196209

@@ -203,7 +216,68 @@ swagger.docket.bbb.basePackage=com.yonghui
203216
- `@Size`
204217
- `@Pattern`
205218

219+
### 自定义全局响应消息配置(1.6.0 + 支持)
220+
221+
支持 POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE 全局响应消息配置,配置如下
222+
223+
```properties
224+
// 取消使用默认预定义的响应消息,并使用自定义响应消息
225+
swagger.apply-default-response-messages=false
226+
swagger.global-response-message.get[0].code=401
227+
swagger.global-response-message.get[0].message=401get
228+
swagger.global-response-message.get[1].code=500
229+
swagger.global-response-message.get[1].message=500get
230+
swagger.global-response-message.get[1].modelRef=ERROR
231+
swagger.global-response-message.post[0].code=500
232+
swagger.global-response-message.post[0].message=500post
233+
swagger.global-response-message.post[0].modelRef=ERROR
234+
```
235+
236+
### UI功能配置(1.6.0 + 支持)
237+
238+
- 调试按钮的控制(try it out)
239+
240+
```properties
241+
swagger.ui-config.submit-methods=get,delete
242+
```
243+
244+
该参数值为提供调试按钮的HTTP请求类型,多个用,分割。
245+
246+
如果不想开启调试功能,只需要如下设置即可:
247+
248+
```properties
249+
swagger.ui-config.submit-methods=
250+
```
251+
252+
- 其他配置
253+
254+
```properties
255+
# json编辑器
256+
swagger.ui-config.json-editor=false
257+
# 显示请求头
258+
swagger.ui-config.show-request-headers=true
259+
# 页面调试请求的超时时间
260+
swagger.ui-config.request-timeout=5000
261+
```
262+
263+
### ignoredParameterTypes配置(1.6.0 + 支持)
264+
265+
```properties
266+
# 基础配置
267+
swagger.ignored-parameter-types[0]=com.didispace.demo.User
268+
swagger.ignored-parameter-types[1]=com.didispace.demo.Product
269+
270+
# 分组配置
271+
swagger.docket.aaa.ignored-parameter-types[0]=com.didispace.demo.User
272+
swagger.docket.aaa.ignored-parameter-types[1]=com.didispace.demo.Product
273+
```
274+
275+
> 该参数作用:
276+
> Q. Infinite loop when springfox tries to determine schema for objects with nested/complex constraints?
277+
> A. If you have recursively defined objects, I would try and see if providing an alternate type might work or perhaps even ignoring the offending classes e.g. order using the docket. ignoredParameterTypes(Order.class). This is usually found in Hibernate domain objects that have bidirectional dependencies on other objects.
278+
206279
## 贡献者
207280

208281
- [程序猿DD-翟永超](https://github.com/dyc87112/)
209282
- [小火](https://renlulu.github.io/)
283+
- [泥瓦匠BYSocket](https://github.com/JeffLi1993)

pom.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<modelVersion>4.0.0</modelVersion>
66

77
<groupId>com.spring4all</groupId>
8-
<artifactId>spring-boot-starter-swagger</artifactId>
9-
<version>1.5.1.RELEASE</version>
8+
<artifactId>swagger-spring-boot-starter</artifactId>
9+
<version>1.6.0.RELEASE</version>
1010

1111
<name>spring-boot-starter-swagger</name>
1212
<url>https://github.com/SpringForAll/spring-boot-starter-swagger</url>
@@ -84,6 +84,11 @@
8484
<version>1.16.12</version>
8585
<scope>provided</scope>
8686
</dependency>
87+
<dependency>
88+
<groupId>org.springframework.boot</groupId>
89+
<artifactId>spring-boot-starter-web</artifactId>
90+
<optional>true</optional>
91+
</dependency>
8792
</dependencies>
8893

8994
<dependencyManagement>

src/main/java/com/spring4all/swagger/SwaggerAutoConfiguration.java

Lines changed: 104 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77
import org.springframework.beans.factory.BeanFactory;
88
import org.springframework.beans.factory.BeanFactoryAware;
99
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
10+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
1011
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
1112
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
1213
import org.springframework.context.annotation.Bean;
1314
import org.springframework.context.annotation.Configuration;
1415
import org.springframework.context.annotation.Import;
15-
import springfox.documentation.builders.ApiInfoBuilder;
16-
import springfox.documentation.builders.ParameterBuilder;
17-
import springfox.documentation.builders.PathSelectors;
18-
import springfox.documentation.builders.RequestHandlerSelectors;
16+
import org.springframework.util.StringUtils;
17+
import org.springframework.web.bind.annotation.RequestMethod;
18+
import springfox.documentation.builders.*;
1919
import springfox.documentation.schema.ModelRef;
2020
import springfox.documentation.service.ApiInfo;
2121
import springfox.documentation.service.Contact;
2222
import springfox.documentation.service.Parameter;
23+
import springfox.documentation.service.ResponseMessage;
2324
import springfox.documentation.spi.DocumentationType;
2425
import springfox.documentation.spring.web.plugins.Docket;
26+
import springfox.documentation.swagger.web.UiConfiguration;
2527

2628
import java.util.*;
2729
import java.util.stream.Collectors;
@@ -45,8 +47,22 @@ public SwaggerProperties swaggerProperties() {
4547
return new SwaggerProperties();
4648
}
4749

50+
@Bean
51+
public UiConfiguration uiConfiguration(SwaggerProperties swaggerProperties) {
52+
return new UiConfiguration(
53+
swaggerProperties.getUiConfig().getValidatorUrl(),// url
54+
swaggerProperties.getUiConfig().getDocExpansion(), // docExpansion => none | list
55+
swaggerProperties.getUiConfig().getApiSorter(), // apiSorter => alpha
56+
swaggerProperties.getUiConfig().getDefaultModelRendering(), // defaultModelRendering => schema
57+
swaggerProperties.getUiConfig().getSubmitMethods().split(","),
58+
swaggerProperties.getUiConfig().getJsonEditor(), // enableJsonEditor => true | false
59+
swaggerProperties.getUiConfig().getShowRequestHeaders(), // showRequestHeaders => true | false
60+
swaggerProperties.getUiConfig().getRequestTimeout()); // requestTimeout => in milliseconds, defaults to null (uses jquery xh timeout)
61+
}
62+
4863
@Bean
4964
@ConditionalOnMissingBean
65+
@ConditionalOnBean(UiConfiguration.class)
5066
@ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true)
5167
public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {
5268
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
@@ -82,20 +98,30 @@ public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {
8298
excludePath.add(PathSelectors.ant(path));
8399
}
84100

85-
Docket docket = new Docket(DocumentationType.SWAGGER_2)
101+
Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2)
86102
.host(swaggerProperties.getHost())
87103
.apiInfo(apiInfo)
88104
.globalOperationParameters(buildGlobalOperationParametersFromSwaggerProperties(
89-
swaggerProperties.getGlobalOperationParameters()))
90-
.select()
105+
swaggerProperties.getGlobalOperationParameters()));
106+
107+
// 全局响应消息
108+
if (!swaggerProperties.getApplyDefaultResponseMessages()) {
109+
buildGlobalResponseMessage(swaggerProperties, docketForBuilder);
110+
}
111+
112+
Docket docket = docketForBuilder.select()
91113
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
92114
.paths(
93115
Predicates.and(
94116
Predicates.not(Predicates.or(excludePath)),
95117
Predicates.or(basePath)
96118
)
97-
)
98-
.build();
119+
).build();
120+
121+
/** ignoredParameterTypes **/
122+
Class[] array = new Class[swaggerProperties.getIgnoredParameterTypes().size()];
123+
Class[] ignoredParameterTypes = swaggerProperties.getIgnoredParameterTypes().toArray(array);
124+
docket.ignoredParameterTypes(ignoredParameterTypes);
99125

100126
configurableBeanFactory.registerSingleton("defaultDocket", docket);
101127
docketList.add(docket);
@@ -138,12 +164,18 @@ public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {
138164
excludePath.add(PathSelectors.ant(path));
139165
}
140166

141-
Docket docket = new Docket(DocumentationType.SWAGGER_2)
167+
Docket docketForBuilder = new Docket(DocumentationType.SWAGGER_2)
142168
.host(swaggerProperties.getHost())
143169
.apiInfo(apiInfo)
144170
.globalOperationParameters(assemblyGlobalOperationParameters(swaggerProperties.getGlobalOperationParameters(),
145-
docketInfo.getGlobalOperationParameters()))
146-
.groupName(groupName)
171+
docketInfo.getGlobalOperationParameters()));
172+
173+
// 全局响应消息
174+
if (!swaggerProperties.getApplyDefaultResponseMessages()) {
175+
buildGlobalResponseMessage(swaggerProperties, docketForBuilder);
176+
}
177+
178+
Docket docket = docketForBuilder.groupName(groupName)
147179
.select()
148180
.apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage()))
149181
.paths(
@@ -154,17 +186,24 @@ public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {
154186
)
155187
.build();
156188

189+
/** ignoredParameterTypes **/
190+
Class[] array = new Class[docketInfo.getIgnoredParameterTypes().size()];
191+
Class[] ignoredParameterTypes = docketInfo.getIgnoredParameterTypes().toArray(array);
192+
docket.ignoredParameterTypes(ignoredParameterTypes);
193+
157194
configurableBeanFactory.registerSingleton(groupName, docket);
158195
docketList.add(docket);
159196
}
160197
return docketList;
161198
}
162199

200+
163201
@Override
164202
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
165203
this.beanFactory = beanFactory;
166204
}
167205

206+
168207
private List<Parameter> buildGlobalOperationParametersFromSwaggerProperties(
169208
List<SwaggerProperties.GlobalOperationParameter> globalOperationParameters) {
170209
List<Parameter> parameters = Lists.newArrayList();
@@ -216,4 +255,57 @@ private List<Parameter> assemblyGlobalOperationParameters(
216255
resultOperationParameters.addAll(docketOperationParameters);
217256
return buildGlobalOperationParametersFromSwaggerProperties(resultOperationParameters);
218257
}
258+
259+
/**
260+
* 设置全局响应消息
261+
*
262+
* @param swaggerProperties 支持 POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE
263+
* @param docketForBuilder
264+
*/
265+
private void buildGlobalResponseMessage(SwaggerProperties swaggerProperties, Docket docketForBuilder) {
266+
267+
SwaggerProperties.GlobalResponseMessage globalResponseMessages =
268+
swaggerProperties.getGlobalResponseMessage();
269+
270+
// POST,GET,PUT,PATCH,DELETE,HEAD,OPTIONS,TRACE 响应消息体
271+
List<ResponseMessage> postResponseMessages = getResponseMessageList(globalResponseMessages.getPost());
272+
List<ResponseMessage> getResponseMessages = getResponseMessageList(globalResponseMessages.getGet());
273+
List<ResponseMessage> putResponseMessages = getResponseMessageList(globalResponseMessages.getPut());
274+
List<ResponseMessage> patchResponseMessages = getResponseMessageList(globalResponseMessages.getPatch());
275+
List<ResponseMessage> deleteResponseMessages = getResponseMessageList(globalResponseMessages.getDelete());
276+
List<ResponseMessage> headResponseMessages = getResponseMessageList(globalResponseMessages.getHead());
277+
List<ResponseMessage> optionsResponseMessages = getResponseMessageList(globalResponseMessages.getOptions());
278+
List<ResponseMessage> trackResponseMessages = getResponseMessageList(globalResponseMessages.getTrace());
279+
280+
docketForBuilder.useDefaultResponseMessages(swaggerProperties.getApplyDefaultResponseMessages())
281+
.globalResponseMessage(RequestMethod.POST, postResponseMessages)
282+
.globalResponseMessage(RequestMethod.GET, getResponseMessages)
283+
.globalResponseMessage(RequestMethod.PUT, putResponseMessages)
284+
.globalResponseMessage(RequestMethod.PATCH, patchResponseMessages)
285+
.globalResponseMessage(RequestMethod.DELETE, deleteResponseMessages)
286+
.globalResponseMessage(RequestMethod.HEAD, headResponseMessages)
287+
.globalResponseMessage(RequestMethod.OPTIONS, optionsResponseMessages)
288+
.globalResponseMessage(RequestMethod.TRACE, trackResponseMessages);
289+
}
290+
291+
/**
292+
* 获取返回消息体列表
293+
*
294+
* @param globalResponseMessageBodyList
295+
* @return
296+
*/
297+
private List<ResponseMessage> getResponseMessageList(List<SwaggerProperties.GlobalResponseMessageBody> globalResponseMessageBodyList) {
298+
List<ResponseMessage> responseMessages = new ArrayList<>();
299+
for (SwaggerProperties.GlobalResponseMessageBody globalResponseMessageBody : globalResponseMessageBodyList) {
300+
ResponseMessageBuilder responseMessageBuilder = new ResponseMessageBuilder();
301+
responseMessageBuilder.code(globalResponseMessageBody.getCode()).message(globalResponseMessageBody.getMessage());
302+
303+
if (!StringUtils.isEmpty(globalResponseMessageBody.getModelRef())) {
304+
responseMessageBuilder.responseModel(new ModelRef(globalResponseMessageBody.getModelRef()));
305+
}
306+
responseMessages.add(responseMessageBuilder.build());
307+
}
308+
309+
return responseMessages;
310+
}
219311
}

0 commit comments

Comments
 (0)