Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HATEOAS methods not found

My controller can't seem to find the HATEOAS methods like "linkTo".

Am I missing something?

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>provider</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.1.5.RELEASE</version>
    </parent>

    <dependencies>

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

        <!-- Spring Security -->
        <!-- Auto configured, remove dependencies to disable. -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
        </dependency>

        <!-- OAuth 2.0 -->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test-mvc</artifactId>
            <version>1.0.0.M2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

        <!-- Spring MongoDB -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
        </dependency>

        <!-- Spring REST MVC -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-rest-webmvc</artifactId>
        </dependency>

        <!-- Dozer: DTO/Entity Mapper -->
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
            <version>5.3.2</version>
        </dependency>

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

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

    </dependencies>

    <properties>
        <start-class>com.provider.core.Application</start-class>
    </properties>

    <build>
        <plugins>
            <plugin> 
                <artifactId>maven-compiler-plugin</artifactId> 
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.spring.io/libs-snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

Controller

package com.provider.core;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.provider.account.Account;
import com.provider.account.AccountDTO;

@Controller
public class AccountController
{
    private static final Logger logger = LoggerFactory.getLogger(AccountController.class);
    @Autowired private AccountRepository repo;

    @RequestMapping(value = "account", method = RequestMethod.POST)
    public @ResponseBody HttpEntity<AccountDTO> createAccount(@RequestBody AccountDTO accountDto) {
        logger.info("Start createAccount()");
        Mapper mapper = new DozerBeanMapper();
        Account account = mapper.map(accountDto, Account.class);
        Account savedAccount = repo.save(account);
        AccountDTO savedAccountDto = mapper.map(savedAccount, AccountDTO.class);

        // DOES NOT COMPILE "linkto" not defined.
        savedAccountDto.add(linkTo(AccountController.class).slash(savedAccountDto.getId()).withSelfRel());

        return new ResponseEntity<AccountDTO>(savedAccountDto, HttpStatus.OK);
    }
}
like image 842
Nestor Ledon Avatar asked Aug 17 '14 19:08

Nestor Ledon


People also ask

What is spring boot starter Hateoas?

The Spring HATEOAS project is a library of APIs that we can use to easily create REST representations that follow the principle of HATEOAS (Hypertext as the Engine of Application State).


4 Answers

In case you are using HATEOAS v1.0 and above (Spring boot >= 2.2.0), do note that the classnames have changed. Notably the below classes have been renamed:

  • ResourceSupport changed to RepresentationModel
  • Resource changed to EntityModel
  • Resources changed to CollectionModel
  • PagedResources changed to PagedModel
  • ResourceAssembler changed to RepresentationModelAssembler

More information available in the official documentation here.

When using Spring boot starter, the below dependency would suffice to include HATEOAS:

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

Hoping this information will help someone like me who searched for hours to find why Resource class was not getting resolved.

like image 129
Nitin Avatar answered Oct 19 '22 05:10

Nitin


Looks like your POM is missing the spring-hateoas dependency.

So first add this to pom.xml:

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

Then you can add this static import and your code should compile:

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*
like image 39
superEb Avatar answered Oct 19 '22 06:10

superEb


If you are using HATEOAS in eclipse(Version : Oxygen.3a Release (4.7.3a)), please note that the class names have changed.

Resource changed to EntityModel
Resources changed to CollectionModel

More information available in the official documentation below link ->

https://docs.spring.io/spring-hateoas/docs/current/reference/html/

When using Spring boot starter, you've to use below dependency to include HATEOAS:

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

Demo Code :

EntityModel<Users> resource = new EntityModel<Users>(user);
        ControllerLinkBuilder linkTo = linkTo(methodOn(this.getClass()).retrieveAllUsers());
        resource.add(linkTo.withRel("all-users"));

Note : You have to import

import static org.springframework.hateoas.server.mvc.ControllerLinkBuilder.*;

Hope this information is helpful to find why Resource class was not getting resolved !!

like image 6
Prithwish Banerjee Avatar answered Oct 19 '22 07:10

Prithwish Banerjee


    Add following dependency :-

    <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-hateoas</artifactId>
     <version>2.4.0</version>
    </dependency>
    
    Follow Sample Code :-
    import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;
   
    @GetMapping(path = "/users/{id}")
    public EntityModel<User> getUserInfo(@PathVariable int id) {
        User user = userDao.getUser(id);
        
        EntityModel<User> entityModel = EntityModel.of(user);
        Link link = WebMvcLinkBuilder.linkTo(methodOn(this.getClass()).getUserList()).withRel("user-list");
        entityModel.add(link);
        
        if(user == null) {
            throw new UserNotFoundException("User not found with id : "+id);
        }
        return entityModel;
    }
like image 6
Ranjit Soni Avatar answered Oct 19 '22 07:10

Ranjit Soni