首页 > 代码库 > 在springboot中整合jersey和springfox-swagger2

在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=http://www.mamicode.com/‘/webjars/bootstrap/3.1.0/css/bootstrap.min.css‘ >

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="image/png" href="http://www.mamicode.com/webjars/swagger-ui/images/favicon-32x32.png" sizes="32x32" />
  <link rel="icon" type="image/png" href="http://www.mamicode.com/webjars/swagger-ui/images/favicon-16x16.png" sizes="16x16" />
  <link href=http://www.mamicode.com/‘/webjars/swagger-ui/css/typography.css‘ media=‘screen‘ rel=‘stylesheet‘ type=‘text/css‘/>"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="http://www.mamicode.com/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="http://www.mamicode.com/#" 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