I am working on spring-boot project where I am working with hateoas. I am using IntelliJ IDE, I have added spring-boot-starter-hateoas dependency in pom.xml but it is giving me an error (cannot resolve symbol) when I try to import org.springframework.hateoas.Resource and org.springframework.hateoas.mvc.ControllerLinkBuilder.
This is my pom.xml file.
<?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>
This is my controller.
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;
}
}
I tried to change versions of spring-boot-starter-hateoas but nothing worked. I also tried to switch to
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.15.0.RELEASE</version>
</dependency>
Using spring-hateoas, there is no compile error but it gives me this following exception when I try to run the application:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: 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
I don't understand where is the problem and not sure either to use spring-boot-starter-hateoas or spring-hateoas.
Spring Boot 2.5.x requires Spring HATEOAS 1.3. As you have seen, downgrading to 0.x will not work.
The 1.0 release of Spring HATEOAS included a number of breaking API changes. You should use EntityModel
in place of Resource
and WebMvcLinkBuilder
in place of ControllerLinkBuilder
. You can learn a little more in this blog post . There's also a script that can be used to help with the migration.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.