在springboot中整合jersey和springfox-swagger2

     2022-03-14     197

关键词:

前言

为了实现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整合markdown实现图片上传和图片再次回显(详细步骤)(代码片段)

SpringBoot整合Markdown实现图片的上传和再次回显前期准备要有markdown的资源文件可以去markdown官网下载资源下载成功后文件中的目录在整合的过程中再将我们需要的资源导入到项目中效果图编写时的效果图再次回显的效果图具体实... 查看详情

springboot整合markdown实现图片上传和图片再次回显(详细步骤)(代码片段)

SpringBoot整合Markdown实现图片的上传和再次回显前期准备要有markdown的资源文件可以去markdown官网下载资源下载成功后文件中的目录在整合的过程中再将我们需要的资源导入到项目中效果图编写时的效果图再次回显的效果图具体实... 查看详情

springboot:springboot整合logback和pagehelper

文章目录SpringBoot整合Logback和PageHelper一、整合Logback二、整合PageHelperSpringBoot整合Logback和PageHelper一、整合LogbackSpringBoot默认使用Logback组件作为日志管理。Logback是由log4j创始人设计的一个开源日志组件。在SpringBoot项目中我们不需要... 查看详情

springboot整合shiro涉及跨域和@cacheable缓存/@transactional事务注解失效问题

...离项目中)  (1) 跨域介绍可参考:跨域(CORS)  (2)SpringBoot中解决跨域方式有:    A.使用@CrossOrigin注解;    B.实现Filter类,重写doFilter方法packagecom.ruhuanxingyun.config;importcn.hutool.core.util.StrUtil;importorg.spri 查看详情

#springboot集成netty(代码片段)

SpringBoot集成Netty文章目录SpringBoot集成Netty背景描述Netty与SpringBoot整合关注点Netty组件Bootstrap、ServerBootstrapChannelEventLoop、EventLoopGroupChannelHandlerChannelPipelineByteBufPom依赖Yml配置整合Netty步骤服务端客户端背景描述如果需要在Spri 查看详情

springboot整合redis,推荐整合和使用案例(2021版)(代码片段)

背景:手下新人在初次使用springboot整合redis,大部分人习惯从网上检索到一份配置,然后不知其所以然的复制粘贴到项目中,网上搜索到的配置良莠不齐但又万变不离其宗。由于springboot最大化地简化了整合redis需... 查看详情

springboot整合redis

1、引入依赖包<!--引入redis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、添加配置文件spri 查看详情

jersey和springboot应用程序抛出java.lang.stackoverflowerror(代码片段)

[尝试使用Jersey创建一个Spring-boot应用程序以响应REST调用。代码类似于此question。该应用程序成功启动,但是当进行REST调用时,会出现无限循环,如在日志中看到的,并在一段时间后引发异常。appContext.xml<?xmlversion="1.0"encoding="UT... 查看详情

Spring boot、jwt、jersey、spring security和CORS问题

】Springboot、jwt、jersey、springsecurity和CORS问题【英文标题】:Springboot,jwt,jersey,springsecurityandCORSissue【发布时间】:2017-09-0915:21:28【问题描述】:我已经开发了一个SpringBootRESTAPI。我有一个CORS错误。我已经在我的端点类中添加了这... 查看详情

springboot整合mybatis(代码片段)

SpringBoot整合MyBatisSpringBoot整合MyBatisSpringBoot是一个快速开发应用程序的框架,而MyBatis是一个提供ORM支持的优秀框架。在本文中,我们将学习如何将SpringBoot与MyBatis整合,以便我们能够更加轻松地开发Web应用程序。步骤创建新的Spri... 查看详情

上手springboot项目之springboot整合shiro安全框架

题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些问题记录下来,作为自己的学习心得。在这先感谢群主TyCoding的Tumo项... 查看详情

第五篇:springboot整合mybatis

前言  前面两篇文章和读者聊了SpringBoot中最简单的数据持久化方案JdbcTemplate,JdbcTemplate虽然简单,但是用的并不多,因为它没有MyBatis方便,在Spring+SpringMVC中整合MyBatis步骤还是有点复杂的,要配置多个Bean,SpringBoot中对此做了... 查看详情

springboot整合springseesion实现redis缓存

参考技术A使用SpringBoot开发项目时我们经常需要存储Session,因为Session中会存一些用户信息或者登录信息。传统的web服务是将session存储在内存中的,一旦服务挂了,session也就消失了,这时候我们就需要将session存储起来,而Redis就... 查看详情

springboot整合dubbo和zookeeper

...就像调用本地服务一样简单。截至目前,Dubbo发布了基于SpringBoot构建的版本,版本号为0.2.0,这使得其与SpringBoot项目整合变得更为简单方便。而Zookeeper在这里充当的是服务注册中心的角色,我们将各个微服务提供的服务通过Dubbo... 查看详情

springboot教程:整合thymeleaf(中)

一、Thymeleaf有哪些优点  1.Thymeleaf在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持html原型,然后在html标签里增加额... 查看详情

springboot整合redis

SpringBoot操作数据层:spring-dataSpringdata和springboot是齐名的项目!说明:在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce?Jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedispool连接池!更像B... 查看详情

springboot整合监听器

Listener是servlet规范中定义的一种特殊类,用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件,监听域对象的属性发生修改的事件。用于在事件发生前后做一些必要的处理。对ServletContext的监听ServletContextListener... 查看详情

springboot整合orm开发框架mybatis和jpa

...中,为了达到简化的目的,往往会进行大量的配置。利用SpringBoot可以进一步实现配置的简化。SpringBoot整合MyBatis开发框架,MyBatis是一款常用并且配置极为简单的ORM开发框架。其与Spring结合后,可以利用Spring的特征实现DAO接口的... 查看详情