Spring boot & Swagger 2 UI & custom requestmappinghandlermapping - 映射问题
Spring boot & Swagger 2 UI & custom requestmappinghandlermapping - mapping issue
我有自己的 RequestMappingHandlerMapping,我正在使用 springfox-swagger-ui。添加我的自定义映射后,我无法在 http://localhost:8080/swagger-ui.html 处实现 swagger ui。
有什么想法吗?
这是我的配置。
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("(META-INF/resources/webjars");
}
}
这是我的 pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
当您覆盖 WebMvcConfigurationSupport 时,您也会覆盖 spring Boot 的 mvc 自动配置 (WebMvcAutoConfiguration)。因此,需要 spring 引导配置的资源将不起作用。这不是 swagger 特有的问题。
您可以在此处找到更多相关信息:
https://github.com/spring-projects/spring-boot/issues/5004
正如 github 问题所暗示的那样,将来会对此进行更改以使其更容易。目前有一些解决方法,如那里所建议的那样。
一种快速而肮脏的方法是将 WebMvcAutoConfiguration class 复制并粘贴到您自己的 class 中,从 EnableWebMvcConfiguration 的 requestMappingHandlerMapping() 方法返回您自己的 HandlerMapping 并注册副本WebMvcAutoConfiguration 的自动配置 class。您可以在此处查看说明:
确保将 WebMvcAutoConfiguration 的副本放在某个未自动扫描和提取组件的包中。它应该按照上面 link.
中的说明进行注册
还要确保在从 requestMappingHandlerMapping() 方法返回之前将自定义 HandlerMapping 的顺序设置为 0,如下所示:
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
ApiVersionRequestMappingHandlerMapping handlerMapping = new ApiVersionRequestMappingHandlerMapping("v");
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors());
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
PathMatchConfigurer configurer = getPathMatchConfigurer();
if (configurer.isUseSuffixPatternMatch() != null) {
handlerMapping.setUseSuffixPatternMatch(configurer.isUseSuffixPatternMatch());
}
if (configurer.isUseRegisteredSuffixPatternMatch() != null) {
handlerMapping.setUseRegisteredSuffixPatternMatch(configurer.isUseRegisteredSuffixPatternMatch());
}
if (configurer.isUseTrailingSlashMatch() != null) {
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch());
}
if (configurer.getPathMatcher() != null) {
handlerMapping.setPathMatcher(configurer.getPathMatcher());
}
if (configurer.getUrlPathHelper() != null) {
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
}
return handlerMapping;
}
终于找到了!
正确的配置是这样的:
@Configuration
public class VersioningMappingHandlerConfig {
@Bean
public ApiVersionRequestMappingHandlerMapping customMappingHandlerMapping() {
ApiVersionRequestMappingHandlerMapping handler = new ApiVersionRequestMappingHandlerMapping("v", 1, 1);
handler.setOrder(-1);
return handler;
}
}
注意:没有extends WebMvcConfigurationSupport
并且bean的名字是customMappingHandlerMapping
对我有用。
覆盖 addResourceHandlers 而不是注册自动配置。
@Configuration
@EnableWebMvc
@EnableSwagger2
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
覆盖 WebMvcConfigurationSupport
的 requestMappingHandlerMapping()
将关闭 spring 引导的自动配置。要添加自定义 MVC 组件,您可以使用 WebMvcRegistrations。例如,为了提供自定义 RequestMappingHandlerMapping
,我们可以使用 RequestMappingHandlerMapping
的自定义 RequestMappingHandlerMapping
覆盖 getRequestMappingHandlerMapping()
,并通过 webMvcRegistrationsHandlerMapping()
提供它。作为,
@Configuration
class CustomRequestMappingHandlerMapping {
@Bean
public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() {
return new WebMvcRegistrationsAdapter() {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
};
}
}
在Spring Boot 2.0.0 中,有一种更简单的方法可以实现这一点。
创建一个 WebMvcRegistrations
接口的实例作为 bean,并覆盖适当的方法以 return 该对象的自定义版本。 Spring 启动将读取并使用该实例。
在这种情况下,只需要覆盖 getRequestMappingHandlerMapping()
和自定义实现 returned
以上信息来自基于@Nazaret K 提供的链接的跟进。
更多信息请见 https://github.com/spring-projects/spring-boot/issues/5004
可以通过使用 WebMvcConfigurationSupport 并为 swagger 添加资源处理程序来解决:
@Configuration
public class MvcConfiguration extends WebMvcConfigurationSupport {
@Value("${spring.application.name}")
private String applicationName;
//...irrelevant code here
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
我有自己的 RequestMappingHandlerMapping,我正在使用 springfox-swagger-ui。添加我的自定义映射后,我无法在 http://localhost:8080/swagger-ui.html 处实现 swagger ui。 有什么想法吗?
这是我的配置。
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("(META-INF/resources/webjars");
}
}
这是我的 pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
当您覆盖 WebMvcConfigurationSupport 时,您也会覆盖 spring Boot 的 mvc 自动配置 (WebMvcAutoConfiguration)。因此,需要 spring 引导配置的资源将不起作用。这不是 swagger 特有的问题。
您可以在此处找到更多相关信息:
https://github.com/spring-projects/spring-boot/issues/5004
正如 github 问题所暗示的那样,将来会对此进行更改以使其更容易。目前有一些解决方法,如那里所建议的那样。
一种快速而肮脏的方法是将 WebMvcAutoConfiguration class 复制并粘贴到您自己的 class 中,从 EnableWebMvcConfiguration 的 requestMappingHandlerMapping() 方法返回您自己的 HandlerMapping 并注册副本WebMvcAutoConfiguration 的自动配置 class。您可以在此处查看说明:
确保将 WebMvcAutoConfiguration 的副本放在某个未自动扫描和提取组件的包中。它应该按照上面 link.
中的说明进行注册还要确保在从 requestMappingHandlerMapping() 方法返回之前将自定义 HandlerMapping 的顺序设置为 0,如下所示:
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
ApiVersionRequestMappingHandlerMapping handlerMapping = new ApiVersionRequestMappingHandlerMapping("v");
handlerMapping.setOrder(0);
handlerMapping.setInterceptors(getInterceptors());
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
PathMatchConfigurer configurer = getPathMatchConfigurer();
if (configurer.isUseSuffixPatternMatch() != null) {
handlerMapping.setUseSuffixPatternMatch(configurer.isUseSuffixPatternMatch());
}
if (configurer.isUseRegisteredSuffixPatternMatch() != null) {
handlerMapping.setUseRegisteredSuffixPatternMatch(configurer.isUseRegisteredSuffixPatternMatch());
}
if (configurer.isUseTrailingSlashMatch() != null) {
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch());
}
if (configurer.getPathMatcher() != null) {
handlerMapping.setPathMatcher(configurer.getPathMatcher());
}
if (configurer.getUrlPathHelper() != null) {
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
}
return handlerMapping;
}
终于找到了! 正确的配置是这样的:
@Configuration
public class VersioningMappingHandlerConfig {
@Bean
public ApiVersionRequestMappingHandlerMapping customMappingHandlerMapping() {
ApiVersionRequestMappingHandlerMapping handler = new ApiVersionRequestMappingHandlerMapping("v", 1, 1);
handler.setOrder(-1);
return handler;
}
}
注意:没有extends WebMvcConfigurationSupport
并且bean的名字是customMappingHandlerMapping
对我有用。 覆盖 addResourceHandlers 而不是注册自动配置。
@Configuration
@EnableWebMvc
@EnableSwagger2
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
覆盖 WebMvcConfigurationSupport
的 requestMappingHandlerMapping()
将关闭 spring 引导的自动配置。要添加自定义 MVC 组件,您可以使用 WebMvcRegistrations。例如,为了提供自定义 RequestMappingHandlerMapping
,我们可以使用 RequestMappingHandlerMapping
的自定义 RequestMappingHandlerMapping
覆盖 getRequestMappingHandlerMapping()
,并通过 webMvcRegistrationsHandlerMapping()
提供它。作为,
@Configuration
class CustomRequestMappingHandlerMapping {
@Bean
public WebMvcRegistrationsAdapter webMvcRegistrationsHandlerMapping() {
return new WebMvcRegistrationsAdapter() {
@Override
public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
return new ApiVersionRequestMappingHandlerMapping("v");
}
};
}
}
在Spring Boot 2.0.0 中,有一种更简单的方法可以实现这一点。
创建一个 WebMvcRegistrations
接口的实例作为 bean,并覆盖适当的方法以 return 该对象的自定义版本。 Spring 启动将读取并使用该实例。
在这种情况下,只需要覆盖 getRequestMappingHandlerMapping()
和自定义实现 returned
以上信息来自基于@Nazaret K 提供的链接的跟进。 更多信息请见 https://github.com/spring-projects/spring-boot/issues/5004
可以通过使用 WebMvcConfigurationSupport 并为 swagger 添加资源处理程序来解决:
@Configuration
public class MvcConfiguration extends WebMvcConfigurationSupport {
@Value("${spring.application.name}")
private String applicationName;
//...irrelevant code here
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}