前言
为了实现RESTful Webservice和接口说明,基于springboot平台,使用jersey作为JAX-RS的实现,采用swagger文档在线生成工具。
提要
在实现了springboot集成jersey的swagger文档功能,同时满足SpringMVC 整合swagger提供RESTful文档功能。
Springboot 集成swagger 通过springfox-swagger2实现SpringMVC的RESTful文档接口服务;
Springboot 集成 Jersey 通过swagger-jersey2-jaxrs 实现Jersey的文档接口服务;
环境
Springboot 1.5.1.RELEASE
springfox-swagger 2 2.6.1
swagger 1.5.12
详细配置
1、Pom文件
<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>
2、springboot配置文件 application.properties
server.servlet-path = / spring.jersey.application-path = /api
3、springboot启动class
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);
}
}
4、Jersey配置类,整合swagger
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);
}
}
5、Swagger配置类,支持spirngMVC RESTful文档功能
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();
}
}
6、SprintMVC风格的web 服务示例
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";
}
}
7、JAX-RS 实现的服务示例
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!!!";
}
}
8、将swagger-ui包中的index.html复制到static目录下,修改资源文件路径
<!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="p_w_picpath/png" href="webjars/swagger-ui/p_w_picpaths/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="p_w_picpath/png" href="webjars/swagger-ui/p_w_picpaths/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/p_w_picpaths/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>
9、结果展示
http://localhost:8080/ 为Jersey 的文档路径
http://localhost:8080/swagger-ui.html 为SpringMVC的controller文档路径
转载于:https://blog.51cto.com/skyfly/1901744