Spring boot & Swagger 2 UI и пользовательское отображение запросов handlermapping - проблема отображения
У меня есть собственный RequestMappingHandlerMapping, и я использую Springfox-Swagger-UI. После добавления своего пользовательского сопоставления я не могу получить пользовательский интерфейс swagger по адресу http://localhost:8080/swagger-ui.html. Есть идеи?
Это моя конфигурация.
@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>
5 ответов
Я наконец-то нашел это! Правильная конфигурация такая:
@Configuration
public class VersioningMappingHandlerConfig {
@Bean
public ApiVersionRequestMappingHandlerMapping customMappingHandlerMapping() {
ApiVersionRequestMappingHandlerMapping handler = new ApiVersionRequestMappingHandlerMapping("v", 1, 1);
handler.setOrder(-1);
return handler;
}
}
Примечание: нет extends WebMvcConfigurationSupport
и имя боба 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, вы также переопределяете автоматическую настройку Spring Boot mvc (WebMvcAutoConfiguration). Следовательно, ресурсы, для которых требуется конфигурация весенней загрузки, работать не будут. Это не проблема, специфичная для чванства.
Вы можете найти больше информации об этом здесь:
https://github.com/spring-projects/spring-boot/issues/5004
Как предполагает проблема GitHub, в будущем в нее будут внесены изменения, чтобы облегчить ее. В настоящее время есть некоторые обходные пути, как предлагается там.
Быстрый и грязный способ сделать это - скопировать и вставить класс WebMvcAutoConfiguration в ваш собственный класс, вернуть свой собственный HandlerMapping из метода requestMappingHandlerMapping() EnableWebMvcConfiguration и зарегистрировать копию WebMvcAutoConfiguration в качестве класса автоматической конфигурации. Вы можете увидеть инструкции здесь:
Убедитесь, что вы поместили свою копию WebMvcAutoConfiguration в какой-то пакет, который не сканируется компонентом и не подбирается автоматически. Это должно быть просто зарегистрировано, как объяснено в ссылке выше.
Также убедитесь, что вы установили порядок своего пользовательского HandlerMapping на 0, прежде чем возвращать его из метода requestMappingHandlerMapping(), например так:
@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;
}
Переопределение requestMappingHandlerMapping()
из WebMvcConfigurationSupport
отключит автоматическую настройку пружинной загрузки. Для добавления пользовательских компонентов MVC вы можете использовать WebMvcRegistrations. Как, для предоставления пользовательских RequestMappingHandlerMapping
Мы можем переопределить getRequestMappingHandlerMapping()
с заказным RequestMappingHandlerMapping
изWebMvcRegistrationsAdapter
и предоставить его через 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
интерфейс как компонент и переопределить соответствующий метод, чтобы вернуть настроенную версию этого объекта. Spring boot будет читать и использовать этот экземпляр.
В этом случае только getRequestMappingHandlerMapping()
должен быть переопределен и возвращена пользовательская реализация
Приведенная выше информация является следствием на основе ссылок, предоставленных @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/");
}
}