使用 Springfox 在 Spring 应用程序中记录 jax-rs 服务

2024-01-18

我想使用 Springfox 记录现有应用程序的 API。我将这些依赖项添加到 pom.xml 中:

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.2.2</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.2.2</version>
</dependency>

我已将 swagger 包添加到 web.xml 中的 jersey 包中,以便选择 Swagger2Controller:

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container, see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application-context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>myapp</filter-name>
        <filter-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</filter-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>org.mystuff;springfox.documentation</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
            <param-value>/WEB-INF/views</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
            <param-value>/(js|css|images|resources)/.*</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.feature.Redirect</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>com.sun.jersey.config.feature.FilterForwardOn404</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>myapp</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

应用程序上下文指定服务的注释等:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:property-placeholder ignore-unresolvable="true" location="classpath*:default.properties, classpath*:${runtime.environment}.properties" />
    <context:annotation-config/>
    <context:component-scan base-package="org.myapp" use-default-filters="true" />

    <aop:aspectj-autoproxy/>
</beans>

配置类如下所示:

@Configuration
@EnableSwagger2
public class ApiDocumentationConfiguration {

    @Bean
    public Docket documentation() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.regex("/api/.*"))
                .build();
    }

    @Bean
    public UiConfiguration uiConfig() {
        return UiConfiguration.DEFAULT;
    }

    private ApiInfo metadata() {
        return new ApiInfoBuilder()
                .title("My awesome API")
                .description("Some description")
                .version("1.0")
                .contact("[email protected] /cdn-cgi/l/email-protection")
                .build();
    }
}

启动时有一个堆栈跟踪:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentationPluginsBootstrapper' defined in URL [jar:file:/home/don/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/DocumentationPluginsBootstrapper.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [springfox.documentation.spi.service.RequestHandlerProvider]: : Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/home/don/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/home/don/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/home/don/.m2/repository/io/springfox/springfox-spring-web/2.2.2/springfox-spring-web-2.2.2.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.util.List]: : No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185)
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping] found for dependency [collection of org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:999)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    ... 71 more

这是集成 Swagger 的最佳方法吗?如果是这样,缺少 bean 的修复方法是什么?或者有更简单的方法吗?

EDIT:

将其添加到 web.xml 可以消除堆栈跟踪:

<bean id="requestMappingHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

但查询http://localhost:9090/myapp/v2/api-docs http://localhost:9090/myapp/v2/api-docs结果是 404,即使启动控制台显示:

2015-09-28 21:54:16,689 INFO  [RequestMappingHandlerMapping] - Mapped "{[/v2/api-docs],methods=[GET]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String)
2015-09-28 21:54:16,690 INFO  [RequestMappingHandlerMapping] - Mapped "{[/configuration/ui]}" onto org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
2015-09-28 21:54:16,690 INFO  [RequestMappingHandlerMapping] - Mapped "{[/configuration/security]}" onto org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
2015-09-28 21:54:16,690 INFO  [RequestMappingHandlerMapping] - Mapped "{[/swagger-resources]}" onto org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()

EDIT:

也可以使用 jax-rs 来映射 SpringFox URI:

<context:component-scan base-package="springfox.documentation" use-default-filters="true" />

...

@Autowired
private Swagger2Controller swagger2Controller;

...

@GET
@Path("/v2/api-docs")
public ResponseEntity<Json> apiDocs() {
    return swagger2Controller.getDocumentation(null);
}

但这并不能满足 SpringFox 所需的完整上下文,因此:

SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.IllegalStateException: Could not find current request via RequestContextHolder. Is this being called from a Spring MVC handler?
    at org.springframework.util.Assert.state(Assert.java:385)
    at org.springframework.hateoas.mvc.ControllerLinkBuilder.getCurrentRequest(ControllerLinkBuilder.java:242)
    at org.springframework.hateoas.mvc.ControllerLinkBuilder.getBuilder(ControllerLinkBuilder.java:189)
    at org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo(ControllerLinkBuilder.java:85)

我将 DispatcherServlet 添加到 web.xml 来处理 Springfox 请求:

<servlet>
    <servlet-name>springfox</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springfox</servlet-name>
    <url-pattern>/v2/api-docs/*</url-pattern>
</servlet-mapping>

接下来我在 WEB-INF 中创建了一个占位符 springfox-servlet.xml。

然后将这些行添加到 application-context.xml 中:

<bean id="swagger2Config" class="org.myapp.api.ApiDocumentationConfiguration"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>

现在,api-docs 请求由 DispatcherServlet 正确路由,应用程序 jax-rs 请求由 Jersey SpringServlet 路由。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Springfox 在 Spring 应用程序中记录 jax-rs 服务 的相关文章

随机推荐

  • 使用 TinyXML 解析 XML 元素

    更新 仍然无法工作 我已经更新了代码部分以反映我当前拥有的内容 对于使用过 TinyXML 的人来说 这应该是一个相当简单的问题 我正在尝试使用 TinyXML 来解析 XML 文档并提取一些值 我昨天弄清楚了如何在库中添加 并且我已经成功
  • Ruby 1.9 中的自动加载是线程安全的吗?

    在我看来 自从 Ruby 社区开始对自动加载感到有点害怕这个著名的线程 http www ruby forum com topic 172385 出于线程安全原因不鼓励使用它 有谁知道这在 Ruby 1 9 1 或 1 9 2 中是否不再是
  • 使用 python 进行非线性回归 - 有什么简单的方法可以更好地拟合这些数据?

    我有一些想要拟合的数据 这样我就可以对给定特定温度的物理参数的值进行一些估计 我使用 numpy polyfit 作为二次模型 但拟合效果并不像我希望的那么好 而且我在回归方面没有太多经验 我已经包含了散点图和 numpy 提供的模型 S
  • MSVC++7.1 中的 ifstream.read() 与 ifstream.readsome()

    我只是采用了在 Linux 下开发的文件阅读器的一些旧代码 并尝试在使用 MSVC 7 1 编译的 Windows 项目中使用相同的代码 代码编译没有任何问题 但根据 Windows 上的文件阅读器 该文件似乎是空的 我跟踪问题到 ifst
  • Azure 流量管理器 SSL 设置(非经典)

    我有一个 Azure API 应用服务 我想为其配置 优先 流量管理 这是新的流量管理器 不是经典的 我已将该服务部署到两个独立的 Azure 区域 并配置了流量管理器实例以执行到两个服务实例的优先级路由 这些服务具有以下自定义域配置 fo
  • 在asp.net应用程序上显示sql数据库中存储的UTC时间的本地时间

    我已经将时间以 utc 格式保存在 SQL 数据库中 我在网格视图上显示这些时间 但它们仍然是 UTC 格式 我想将它们转换为客户端浏览器的本地时间 问题是 虽然我可以获得仅适用于当前日期 时间的时区偏移量 如果未来的某些日期最终发生在夏令
  • 如何在 Angular 2 最终版本中编写 HTTP 模拟单元测试?

    我已从 RC4 迁移到最终版本 2 1 0 并且正在重构我的单元测试以符合 2 1 0 语法 除了 HTTP 模拟之外 这很容易 我找不到任何关于如何在 2 1 0 中模拟 HTTP 请求的示例 这是一个 RC4 HTTP 单元测试 我将如
  • 使用 msbuild 从网站部署中排除文件

    我有一个使用 msbuild 部署的网站项目 在项目中 有一些构建所需的文件和文件夹 例如 web config 部分替换文件 但我不想将其部署到目标站点 我能想到的最好的办法是删除这些文件的构建后目标 但我想知道是否有办法让这些文件不复制
  • 由于占用率低而导致 GPU 利用率不足是什么意思?

    我正在使用 NUMBA 和 cupy 来执行 GPU 编码 现在我已将代码从 V100 NVIDIA 卡切换到 A100 但是随后我收到以下警告 NumbaPerformanceWarning 网格大小 27 NumbaPerformanc
  • VSCode Flutter Dart 慢的建议

    我使用 Visual Studio Code 进行 flutter 编程 并且没有使用很多扩展 我喜欢代码补全 但通常太慢 显示所有建议大约需要 1 2 秒 这个问题有什么解决办法吗 这是我已安装的扩展的列表 我被告知要添加此配置 dart
  • 什么是 WCF 服务参考 .datasource 文件?

    Visual Studio 中 创建服务引用 自动生成的 datasource 文件是什么 文件中的注释是这样的 该文件是自动生成的 由 Visual Studio Net 提供 这是 用于存储通用对象数据源配置信息 重命名文件扩展名或编辑
  • FormData 键作为数组

    我正在尝试使用 FormData html5 api 设置多个文件上传 问题是我无法删除 FormData 键上的数组索引 前任 if editor frmData editor frmData append upload files 0
  • IntelliJ Idea Android 项目包括 apk 中不受监管的文件

    我有一个复杂的应用程序结构 主项目有 android 库 它们有自己的 android 库和 jar 主要工程 Libs Android Lib project A Jars Android Lib项目B Jars 为了澄清起见 我有一个
  • 如何在 Sphinx 文档中显示类的继承成员?

    我想记录一些类 这些类都派生自具有一些公共属性的同一基类 并且我想重复子类中每个属性的文档 以便我可以在一个位置看到一个类的所有属性 例如我有这样的代码 class Base object Base class First attribut
  • 构建 .NET Core 控制台应用程序以输出 EXE

    对于面向 NET Core 1 0 的控制台应用程序项目 我无法弄清楚如何在构建期间输出 exe 该项目在调试中运行良好 我尝试过发布该项目 但这也不起作用 这是有道理的 因为 EXE 文件是特定于平台的 但必须有一种方法 我的搜索仅找到对
  • 如何检查设备是否需要 SafeArea? (需要底部/顶部填充)

    有没有一种方法可以检查运行该应用程序的设备是否需要 SafeArea 我需要根据这个 true 或 false 值运行代码 我不需要使用 SafeArea 小部件 如果设备需要填充 我所需要的只是正确或错误的答案 例如 像iPhone 8这
  • CMake:为每个项目设置编译选项和编译功能

    我有一个代码库 例如 存储库 其中包含多个软件组件 可执行文件 库 所有内容都是使用 CMake 构建的 每个组件都有单独的目标 现在 我知道设置编译器标志的现代方法是特定于目标的 target compile options foo PR
  • 什么是金融运作中的锁定、僵局问题?

    盘问SQL 什么时候应该使用 with nolock https stackoverflow com questions 686724 sql when should you use with nolock 在一家当地的金融机构 我因为向他
  • 记录清单

    以下代码似乎向列表中添加了一条新记录 但会用最后创建的记录覆盖所有记录 我可以让它正常工作 lpr Add new personRecord Age pr Age Name pr Name 但这似乎更冗长 并且在真正的应用程序中记录要大得多
  • 使用 Springfox 在 Spring 应用程序中记录 jax-rs 服务

    我想使用 Springfox 记录现有应用程序的 API 我将这些依赖项添加到 pom xml 中