Resource and ControllerLinkBuilder not found and deprecated
Asked Answered
R

7

16

I am using Spring Boot 2.2.0.M1 with HATEOAS and Gradle.

implementation 'org.springframework.boot:spring-boot-starter-hateoas'

Right now, Resource is not found by the IDE (IntelliJ IDEA 2018.3) and ControllerLinkBuilder is marked as deprecated.

package com.example.restfulwebservicegradle.user;

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

import com.example.restfulwebservicegradle.User;
import com.example.restfulwebservicegradle.UserDaoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.server.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;

@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 not found
        Resource<User> resource = new Resource<User>(user);

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

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

        return resource;
    }
}

The imports available according to the IDE are: enter image description here

How can I solve this?

My goal is to found Resource from HATEOAS and to use the substitute of ControllerLinkBuilder.

Roselinerosella answered 20/4, 2019 at 4:7 Comment(1)
Spring Boot 2.2.0M1 uses Spring HATEOAS 1.0 which has undergone some breaking changes.Insnare
R
28

The most fundamental change is the fact that Spring HATEOAS doesn’t create resources. That’s what Spring MVC/Spring WebFlux does. We create vendor neutral representations of hypermedia. So we renamed those core types:

LINK- https://spring.io/blog/2019/03/05/spring-hateoas-1-0-m1-released#overhaul

  1. ResourceSupport is now RepresentationModel
  2. Resource is now EntityModel
  3. Resources is now CollectionModel
  4. PagedResources is now PagedModel
Roa answered 8/5, 2019 at 14:49 Comment(3)
I'm struggling to find an example on how to feed a controller parameter something that can replace PagedResourcesAssembler<User> pagedResourcesAssemblerDakar
@Dakar Have you found what you were looking for? Would you please share?Sputter
@JinKwon Sorry but I haven't worked on that for years and it's out of my scope at the moment.Dakar
L
17

Resource was replaced by EntityModel, and ControllerLinkBuilder was replaced by WebMvcLinkBuilder

Limemann answered 12/5, 2020 at 2:52 Comment(1)
Precisely what I was looking forUnbiased
P
3

Linking to other replies... following code worked fine for me...

UserResource.java

package com.---.---.restfulwebservices.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
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.server.mvc.WebMvcLinkBuilder.methodOn;

@RestController
public class UserResource {
    @Autowired
    private UserDaoService service;

    @GetMapping(path = "/users")
    public List<User> retrieveAllUsers() {
        return service.findAll();
    }

    @GetMapping(path = "/users/{id}")
    public EntityModel<User> retrieveUser(@PathVariable int id) {
        User user = service.findOne(id);
        if (null == user)
            throw new UserNotFoundException("id-" + id);

        EntityModel<User> entityModel = EntityModel.of(user);
        Link link= WebMvcLinkBuilder.linkTo(
                methodOn(this.getClass()).retrieveAllUsers()).withRel("all-users");
        entityModel.add(link);
        return entityModel;
    }

    @PostMapping(path = "/users")
    public ResponseEntity<Object> createUser(@Valid @RequestBody User user) {
        User newUser = service.saveUser(user);
        URI path = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}").buildAndExpand(newUser.getId()).toUri();
        return ResponseEntity.created(path).build();
    }

    @DeleteMapping(path = "/users/{id}")
    public User deleteUser(@PathVariable int id) {
        User deletedUser = service.deleteUserByID(id);
        if (null == deletedUser)
            throw new UserNotFoundException("id-" + id);
        return deletedUser;
    }
}

pom.xml dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
Philomenaphiloo answered 20/8, 2020 at 12:12 Comment(1)
this is exactly what I'm looking for, thanks for sharingDenison
D
1
UserResource controller = methodOn(UserResource.class);
    EntityModel<User> resource = EntityModel.of(user);

    Link link= WebMvcLinkBuilder.linkTo(controller
            .retriveAllUser()).withRel("all-users");

    resource.add(link);
    return resource;

Here UserResource is Controller retriveAllUser is the method which you want to expose

Decongestant answered 7/7, 2020 at 17:33 Comment(0)
J
0

The biggest changes in package structure were driven by the introduction of a hypermedia type registration API to support additional media types in Spring HATEOAS.

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

Jejune answered 25/2, 2020 at 15:57 Comment(0)
C
0

As mentioned by other fellow coders, many changes (deprecations) have happened in HATEOAS, so please use the following code:

@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 has been replaced by EntityModel
        EntityModel<User> resource = EntityModel.of(user);

        //ControllerLinkBuilder has been replace by WebMvcLinkBuilder
        Link link= WebMvcLinkBuilder.linkTo(methodOn(this.getClass()).retrieveAllUsers()).withRel("all-users");

        resource.add(link);
        return resource;
    }
}

And this is spring-hateoas dependency, you should add this to pom.xml:

<dependency>
    <groupId>org.springframework.hateoas</groupId>
    <artifactId>spring-hateoas</artifactId>
    <version>1.1.0.RELEASE</version>
</dependency>
Calida answered 2/6, 2020 at 15:51 Comment(0)
Z
0

Old classes & corresponding new classes can be found from the spring-hateoas migration script to 1.0:

https://github.com/spring-projects/spring-hateoas/blob/main/etc/migrate-to-1.0.sh

ex:

 ControllerLinkBuilder -> hateoas.server.mvc.WebMvcLinkBuilder
Zechariah answered 7/8, 2022 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.