【问题标题】:org.springframework.hateoas.Resource and org.springframework.hateoas.mvc.ControllerLinkBuilder cannot be found when using spring-boot-starter-hateoas使用spring-boot-starter-hateoas时找不到org.springframework.hateoas.Resource和org.springframework.hateoas.mvc.ControllerLinkBuilder
【发布时间】:2021-07-29 16:33:34
【问题描述】:

我正在从事与 hatoas 合作的 spring-boot 项目。我正在使用 IntelliJ IDE,我在 pom.xml 中添加了 spring-boot-starter-hateoas 依赖项,但是当我尝试导入 org.springframework.hateoas.Resource 和 org.springframework 时,它给了我一个错误(无法解析符号)。 hatoas.mvc.ControllerLinkBuilder.

这是我的 pom.xml 文件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.learn.rest.webservices</groupId>
    <artifactId>restful-web-services</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>restful-web-services</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-rest-hal-explorer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
            <version>1.5.10</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${project.parent.version}</version>
            </plugin>
        </plugins>
    </build>

</project>

这是我的控制器。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.mvc.ControllerLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.validation.Valid;
import java.net.URI;
import java.util.List;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

@RestController
public class UserResource {

    @Autowired
    private UserDaoService service;

    @GetMapping("/users/{id}")
    public Resource<User> retrieveUser(@PathVariable int id) {
        User user = service.findOne(id);

        if(user==null)
            throw new UserNotFoundException("id-"+ id);

        Resource<User> resource = new Resource<User>(user);

        ControllerLinkBuilder linkTo =
                linkTo(methodOn(this.getClass()).retrieveAllUsers());

        resource.add(linkTo.withRel("all-users"));

        return resource;
    }
}

我尝试更改 spring-boot-starter-hateoas 的版本,但没有任何效果。我也尝试切换到

<dependency>
    <groupId>org.springframework.hateoas</groupId>
    <artifactId>spring-hateoas</artifactId>
    <version>0.15.0.RELEASE</version>
</dependency>

使用 spring-hateoas,没有编译错误,但是当我尝试运行应用程序时,它给了我以下异常:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.3)

2021-07-29 12:28:43.501  INFO 16144 --- [  restartedMain] c.l.r.w.r.RestfulWebServicesApplication  : Starting RestfulWebServicesApplication using Java 1.8.0_291 on DESKTOP-U935EU5 with PID 16144 (D:\Java\AllProjects\1.JAVA.V2\microservices\restful-web-services\target\classes started by Parth in D:\Java\AllProjects\1.JAVA.V2\microservices\restful-web-services)
2021-07-29 12:28:43.505  INFO 16144 --- [  restartedMain] c.l.r.w.r.RestfulWebServicesApplication  : No active profile set, falling back to default profiles: default
2021-07-29 12:28:43.601  INFO 16144 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-07-29 12:28:43.601  INFO 16144 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-07-29 12:28:44.765  WARN 16144 --- [  restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.learn.rest.webservices.restfulwebservices.RestfulWebServicesApplication]; nested exception is java.lang.IllegalArgumentException: No enum constant org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType.HAL_FORMS
2021-07-29 12:28:44.783  INFO 16144 --- [  restartedMain] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-07-29 12:28:44.833 ERROR 16144 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [com.learn.rest.webservices.restfulwebservices.RestfulWebServicesApplication]; nested exception is java.lang.IllegalArgumentException: No enum constant org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType.HAL_FORMS
    at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:610) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.access$800(ConfigurationClassParser.java:111) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.lambda$processGroupImports$1(ConfigurationClassParser.java:812) ~[spring-context-5.3.9.jar:5.3.9]
    at java.util.ArrayList.forEach(ArrayList.java:1259) ~[na:1.8.0_291]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:780) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) [spring-boot-2.5.3.jar:2.5.3]
    at com.learn.rest.webservices.restfulwebservices.RestfulWebServicesApplication.main(RestfulWebServicesApplication.java:10) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_291]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_291]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_291]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_291]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.5.3.jar:2.5.3]
Caused by: java.lang.IllegalArgumentException: No enum constant org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType.HAL_FORMS
    at java.lang.Enum.valueOf(Enum.java:238) ~[na:1.8.0_291]
    at org.springframework.core.type.classreading.MergedAnnotationReadingVisitor.visitEnum(MergedAnnotationReadingVisitor.java:104) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.type.classreading.MergedAnnotationReadingVisitor$ArrayVisitor.visitEnum(MergedAnnotationReadingVisitor.java:169) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.readElementValue(ClassReader.java:3079) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.readElementValues(ClassReader.java:3004) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.readElementValue(ClassReader.java:3178) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.readElementValues(ClassReader.java:2998) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.accept(ClassReader.java:608) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.asm.ClassReader.accept(ClassReader.java:424) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:86) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:73) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:696) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getRelated(ConfigurationClassParser.java:1090) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getAnnotationAttributes(ConfigurationClassParser.java:1071) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.collectImports(ConfigurationClassParser.java:549) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.getImports(ConfigurationClassParser.java:522) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:311) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:250) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:600) ~[spring-context-5.3.9.jar:5.3.9]
    ... 24 common frames omitted

我不明白问题出在哪里,也不确定是使用 spring-boot-starter-hateoas 还是 spring-hateoas。

【问题讨论】:

    标签: java spring-boot maven


    【解决方案1】:

    Spring Boot 2.5.x 需要 Spring HATEOAS 1.3。如您所见,降级到 0.x 是行不通的。

    Spring HATEOAS 的 1.0 版本包括许多重大的 API 更改。 您应该使用EntityModel 代替ResourceWebMvcLinkBuilder 代替ControllerLinkBuilder。您可以在this blog post 了解更多信息。还有a script 可用于帮助迁移。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 2021-05-31
      • 2015-07-07
      • 2017-08-10
      • 2017-02-19
      • 2014-04-07
      • 2019-08-06
      相关资源
      最近更新 更多