【问题标题】:Generate Swagger.json using Springfox for OASP4j (Spring boot) cxf Rest services使用 Springfox 为 OASP4j (Spring boot) cxf Rest services 生成 Swagger.json
【发布时间】:2018-11-22 00:47:53
【问题描述】:

我正在尝试为我们的项目生成一个基于 OASP4J 的 swagger.json。它使用 spring boot 和 Apache cxf 服务框架来开发 Rest 服务。 我已经尝试过不同的教程,但似乎没有任何效果。 主要问题是生成了文件但是api列表是空的。每个rest服务都在这个路径下localhost:8081/attivazioni/services/rest/general/v1/

SpringBootApp.java

@SpringBootApplication(exclude = { EndpointAutoConfiguration.class })
@EntityScan(basePackages = { "\"it.lispa.sire.attivazioni" }, basePackageClasses = { AdvancedRevisionEntity.class })
@EnableSwagger2
@EnableGlobalMethodSecurity(jsr250Enabled = true)
public class SpringBootApp {

  /**
   * Entry point for spring-boot based app
   *
   * @param args - arguments
   */
  public static void main(String[] args) {

    SpringApplication.run(SpringBootApp.class, args);
  }
}

JerseyConfig.java

@Component
@ApplicationScope("/attivazioni")
public class JerseyConfig extends ResourceConfig {

  public JerseyConfig() {

    BeanConfig swaggerConfig = new BeanConfig();
    swaggerConfig.setBasePath("/attivazioni");
    SwaggerConfigLocator.getInstance().putConfig(SwaggerContextService.CONFIG_ID_DEFAULT, swaggerConfig);

    packages(getClass().getPackage().getName(), ApiListingResource.class.getPackage().getName());
  }

}

CombinedSwaggerResourcesProvider.java

@Component
@Primary
public class CombinedSwaggerResourcesProvider implements SwaggerResourcesProvider {

  @Resource
  private InMemorySwaggerResourcesProvider inMemorySwaggerResourcesProvider;

  @Override
  public List<SwaggerResource> get() {

    SwaggerResource jerseySwaggerResource = new SwaggerResource();
    jerseySwaggerResource.setLocation("/attivazioni/swagger.json");
    jerseySwaggerResource.setSwaggerVersion("2.0");
    jerseySwaggerResource.setName("Jersey");

    return Stream.concat(Stream.of(jerseySwaggerResource), this.inMemorySwaggerResourcesProvider.get().stream())
        .collect(Collectors.toList());
  }

}

ServiceConfig.java

@Configuration
@EnableWs
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class ServiceConfig extends WsConfigurerAdapter {

  /** Logger instance. */
  private static final Logger LOG = LoggerFactory.getLogger(ServiceConfig.class);

  /** The services "folder" of an URL. */
  public static final String URL_FOLDER_SERVICES = "services";

  public static final String URL_PATH_SERVICES = "/private/" + URL_FOLDER_SERVICES;

  public static final String URL_FOLDER_REST = "/rest";

  public static final String URL_FOLDER_WEB_SERVICES = "/ws";

  public static final String URL_PATH_REST_SERVICES = URL_PATH_SERVICES + "/" + URL_FOLDER_REST;

  public static final String URL_PATH_WEB_SERVICES = URL_PATH_SERVICES + "/" + URL_FOLDER_WEB_SERVICES;

  @Value("${security.expose.error.details}")
  boolean exposeInternalErrorDetails;

  @Inject
  private ApplicationContext applicationContext;

  @Inject
  private ObjectMapperFactory objectMapperFactory;

  @Bean(name = "cxf")
  public SpringBus springBus() {

    return new SpringBus();
  }

  @Bean
  public JacksonJsonProvider jacksonJsonProvider() {

    return new JacksonJsonProvider(this.objectMapperFactory.createInstance());
  }

  @Bean
  public ServletRegistrationBean servletRegistrationBean() {

    CXFServlet cxfServlet = new CXFServlet();
    ServletRegistrationBean servletRegistration = new ServletRegistrationBean(cxfServlet, URL_PATH_SERVICES + "/*");
    return servletRegistration;
  }

  @Bean
  public Server jaxRsServer() {

    // List<Object> restServiceBeans = new
    // ArrayList<>(this.applicationContext.getBeansOfType(RestService.class).values());
    Collection<Object> restServices = findRestServices();
    if (restServices.isEmpty()) {
      LOG.info("No REST Services have been found. Rest Endpoint will not be enabled in CXF.");
      return null;
    }
    Collection<Object> providers = this.applicationContext.getBeansWithAnnotation(Provider.class).values();

    JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
    factory.setBus(springBus());
    factory.setAddress(URL_FOLDER_REST);
    factory.setServiceBeans(new ArrayList<>(restServices));
    factory.setProviders(new ArrayList<>(providers));
    return factory.create();
  }

  private Collection<Object> findRestServices() {

    return this.applicationContext.getBeansWithAnnotation(Path.class).values();
  }

  @Bean
  public RestServiceExceptionFacade restServiceExceptionFacade() {

    RestServiceExceptionFacade exceptionFacade = new RestServiceExceptionFacade();
    exceptionFacade.setExposeInternalErrorDetails(this.exposeInternalErrorDetails);
    return exceptionFacade;
  }

}

pom.xml

...
<dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>2.8.0</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>2.8.0</version>
    </dependency>
    <dependency>
      <groupId>io.swagger</groupId>
      <artifactId>swagger-jersey2-jaxrs</artifactId>
      <version>1.5.9</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-batch</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-zuul</artifactId>
      <version>${spring-cloud.version}</version>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-logging</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-beanmapping</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-security</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-rest</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-basic</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.starters</groupId>
      <artifactId>oasp4j-starter-cxf-client-rest</artifactId>
    </dependency>
    <dependency>
      <groupId>io.oasp.java.starters</groupId>
      <artifactId>oasp4j-starter-cxf-client-ws</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.starters</groupId>
      <artifactId>oasp4j-starter-cxf-server-rest</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.starters</groupId>
      <artifactId>oasp4j-starter-cxf-server-ws</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-jpa-envers</artifactId>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-web</artifactId>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>

    <!-- for SpringDispatcher Servlet -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
    </dependency>

    <!-- for HttpInvoker -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
    </dependency>

    <!-- JSP -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
    </dependency>

    <!-- Spring Security -->
    <!--
      <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      </dependency>

      <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      </dependency>
    -->

    <!-- for Object Relational Mapping (JPA/Hibernate) -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
    </dependency>

    <!-- Hibernate EntityManager for JPA (implementation) -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
    </dependency>

    <!-- Database -->
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
    </dependency>

    <dependency>
      <groupId>org.flywaydb</groupId>
      <artifactId>flyway-core</artifactId>
    </dependency>

    <!-- hibernate -->
    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
    </dependency>
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
    </dependency>

    <!-- CXF for REST and Webservices -->
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxws</artifactId>
      <exclusions>
        <exclusion>
          <groupId>asm</groupId>
          <artifactId>asm</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-client</artifactId>
    </dependency>

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-service-description</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
    </dependency>

    <!-- Web Sockets -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-websocket</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-messaging</artifactId>
    </dependency>

    <!-- Tests -->
    <dependency>
      <groupId>org.springframework.batch</groupId>
      <artifactId>spring-batch-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>io.oasp.java.modules</groupId>
      <artifactId>oasp4j-test</artifactId>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.3</version>
      <scope>runtime</scope>
    </dependency>

    <dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.3</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
      <groupId>org.scala-lang</groupId>
      <artifactId>scala-library</artifactId>
      <version>2.10.4</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-ws</artifactId>
    </dependency>
...

【问题讨论】:

    标签: maven spring-boot cxf swagger springfox


    【解决方案1】:

    请参考cxf swagger example project,以便从具有Swagger Annotations 的CXF Rest 服务生成swagger.json。您需要添加cxf-rt-rs-service-description-swagger maven 依赖并将Swagger2Feature 添加到JAXRSServerFactoryBean(在您的情况下,您必须设置为factory.setFeatures(new Swagger2Feature())

    【讨论】:

      【解决方案2】:

      我认为您需要创建一个Docket bean,如下所示:

      @Configuration
      @EnableSwagger2
      public class SwaggerConfig {
          @Bean
          public Docket publicApi() {
              return new Docket(DocumentationType.SWAGGER_2)
                      .select()
                      .apis(RequestHandlerSelectors.basePackage("com.foo.bar"))
                      .paths(PathSelectors.ant("/api/**"))
                      .build()
                      .securitySchemes(Collections.singletonList(new BasicAuth("basic")))
                      .apiInfo(apiInfo());
          }
      
          private ApiInfo apiInfo() {
              return new ApiInfo(
                      "REST Service API",
                      "V1 Service API endpoints",
                      "1",
                      "Terms of Service",
                      new Contact("Digital Support", "www.foo.bar", "digitalsupport@foo.bar"),
                      "Apache 2.0",
                      "http://www.apache.org/licenses/LICENSE-2.0.html",
                      Collections.<VendorExtension>emptyList()
              );
          }
      }
      

      我将它放在一个独立的配置类中,而不是将它放在主 spring-boot 应用程序类中。

      除了这个配置之外,唯一的东西是控制器方法上的一些注释,如下所示:@ApiOperation(value = "Get Paged Accounts. Requires ADMIN Role", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)

      【讨论】:

      • 我已经尝试过使用 docket 但 Springfox 只找到带有“@RestController”注释的类,而不是带有“@Path”注释的 cxf 类
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-27
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-10
      相关资源
      最近更新 更多