问题描述
我必须在SpringBoot上构建REST服务。我的团队使用Swagger进行API测试,因此我的入门pom.xml
文件具有相关的依赖性:
<dependencies>
<!-- =========== Spring Boot Dependencies =========== -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.3.3.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- ================= Spring Data JPA ==================== -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
<!-- ================ Swagger =============== -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
</dependencies>
现在只有一个简单的HTTP控制器,甚至没有数据被提供:
@RestController
@RequestMapping(path = "/api")
public class HomeController {
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public ResponseEntity<Object> getHello() {
return new ResponseEntity<>(
new ResponseMessage(ResponseMessage.SUCCESS,"Successfully hit rest service","Hello user"),HttpStatus.OK);
}
}
我的Swagger配置是:
@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("com.company.controller"))
.paths(PathSelectors.any())
.build();
}
@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/");
}
}
该应用程序运行,对http://localhost:8080/swagger-ui.html
的访问非常有成果:
不幸的是,我注意到合并了HATEOAS依赖项:
<!-- https://mvnrepository.com/artifact/org.springframework.hateoas/spring-hateoas -->
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>1.1.1.RELEASE</version> <!-- Same results for 1.1.2.RELEASE -->
</dependency>
使用相当冗长的输出导致项目崩溃:
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration.pageableCustomizer
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitionsForBeanMethod(ConfigurationClassBeanDeFinitionReader.java:180) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitionsForConfigurationClass(ConfigurationClassBeanDeFinitionReader.java:141) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDeFinitionReader.loadBeanDeFinitions(ConfigurationClassBeanDeFinitionReader.java:117) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClasspostProcessor.processConfigBeanDeFinitions(ConfigurationClasspostProcessor.java:328) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClasspostProcessor.postProcessBeanDeFinitionRegistry(ConfigurationClasspostProcessor.java:233) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDeFinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:271) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokebeanfactoryPostProcessors(PostProcessorRegistrationDelegate.java:91) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokebeanfactoryPostProcessors(AbstractApplicationContext.java:694) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at com.company.config.Application.main(Application.java:11) ~[classes/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@368239c8]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:659) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:556) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:541) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:599) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.getTypeForFactoryMethod(AbstractAutowireCapablebeanfactory.java:718) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.determinetargettype(AbstractAutowireCapablebeanfactory.java:659) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.predictBeanType(AbstractAutowireCapablebeanfactory.java:627) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.Abstractbeanfactory.isfactorybean(Abstractbeanfactory.java:1489) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.Abstractbeanfactory.isfactorybean(Abstractbeanfactory.java:1012) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDeFinition(BeanTypeRegistry.java:194) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanTypeForNonAliasDeFinition(BeanTypeRegistry.java:170) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.addBeanType(BeanTypeRegistry.java:163) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.lambda$updateTypesIfNecessary$2(BeanTypeRegistry.java:150) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) ~[na:na]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.updateTypesIfNecessary(BeanTypeRegistry.java:148) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.BeanTypeRegistry.getNamesForType(BeanTypeRegistry.java:114) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:265) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:254) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:196) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:116) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.0.5.RELEASE.jar:2.0.5.RELEASE]
... 17 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/hateoas/mvc/UriComponentsContributor
at java.base/java.lang.classLoader.defineClass1(Native Method) ~[na:na]
at java.base/java.lang.classLoader.defineClass(ClassLoader.java:1017) ~[na:na]
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClasspathOrNull(BuiltinClassLoader.java:698) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522) ~[na:na]
at java.base/java.lang.class.getDeclaredMethods0(Native Method) ~[na:na]
at java.base/java.lang.class.privateGetDeclaredMethods(Class.java:3166) ~[na:na]
at java.base/java.lang.class.getDeclaredMethods(Class.java:2309) ~[na:na]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:641) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
... 37 common frames omitted
Caused by: java.lang.classNotFoundException: org.springframework.hateoas.mvc.UriComponentsContributor
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522) ~[na:na]
... 50 common frames omitted
2020-10-11 16:50:21.499 INFO 10692 --- [ main] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7d446ed1: startup date [Sun Oct 11 16:50:20 EDT 2020]; root of context hierarchy
2020-10-11 16:50:21.500 WARN 10692 --- [ main] o.s.boot.SpringApplication : Unable to close ApplicationContext
java.lang.IllegalStateException: Failed to introspect Class [org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@368239c8]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:659) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:556) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:541) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:599) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.getTypeForFactoryMethod(AbstractAutowireCapablebeanfactory.java:718) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.determinetargettype(AbstractAutowireCapablebeanfactory.java:659) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.predictBeanType(AbstractAutowireCapablebeanfactory.java:627) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.Abstractbeanfactory.isfactorybean(Abstractbeanfactory.java:1489) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListablebeanfactory.doGetBeanNamesForType(DefaultListablebeanfactory.java:419) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeanNamesForType(DefaultListablebeanfactory.java:389) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:510) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:502) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1198) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.boot.SpringApplication.getExitCodeFromMappedException(SpringApplication.java:910) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.getExitCodeFromException(SpringApplication.java:896) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.handleExitCode(SpringApplication.java:882) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:831) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:344) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) ~[spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
at com.company.config.Application.main(Application.java:11) ~[classes/:na]
Caused by: java.lang.NoClassDefFoundError: org/springframework/hateoas/mvc/UriComponentsContributor
at java.base/java.lang.classLoader.defineClass1(Native Method) ~[na:na]
at java.base/java.lang.classLoader.defineClass(ClassLoader.java:1017) ~[na:na]
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClasspathOrNull(BuiltinClassLoader.java:698) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621) ~[na:na]
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522) ~[na:na]
at java.base/java.lang.class.getDeclaredMethods0(Native Method) ~[na:na]
at java.base/java.lang.class.privateGetDeclaredMethods(Class.java:3166) ~[na:na]
at java.base/java.lang.class.getDeclaredMethods(Class.java:2309) ~[na:na]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:641) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
... 20 common frames omitted
Caused by: java.lang.classNotFoundException: org.springframework.hateoas.mvc.UriComponentsContributor
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
at java.base/java.lang.classLoader.loadClass(ClassLoader.java:522) ~[na:na]
... 33 common frames omitted
Process finished with exit code 1
用{p>代替pom.xml
中的两个依赖项
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
不幸的是没有用。
想法?
解决方法
您需要springfox-boot-starter
依赖性,并将@EnableSwagger2
替换为@EnableOpenApi
@Configuration
@EnableOpenApi
public class SwaggerConfig extends WebMvcConfigurationSupport {
@Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("com.company.controller"))
.paths(PathSelectors.any())
.build();
}
@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/");
}
}
注意:Swagger ui将可用于{host}:{port}/{contextPath}/swagger-ui/index.html
网址