在springboot中整合jersey和springfox-swagger2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在springboot中整合jersey和springfox-swagger2相关的知识,希望对你有一定的参考价值。

前言

为了实现RESTful Webservice和接口说明,基于springboot平台,使用jersey作为JAX-RS的实现,采用swagger文档在线生成工具。

提要

在实现了springboot集成jerseyswagger文档功能,同时满足SpringMVC 整合swagger提供RESTful文档功能。

  • Springboot  集成swagger 通过springfox-swagger2实现SpringMVCRESTful文档接口服务;

  • 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",
                // "[email protected]l.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="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>&nbsp;</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文档路径

以上是关于在springboot中整合jersey和springfox-swagger2的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot整合Freemarker

SpringBoot与Nacos整合

springboot整合redis

# SpringBoot 集成 Netty

# SpringBoot 集成 Netty

SpringBoot整合Shiro 涉及跨域和@Cacheable缓存/@Transactional事务注解失效问题