Spring boot教程-为 RESTful 服务实现 HATEOAS
为 RESTful 服务实现 HATEOAS
HATEOAS
HATEOAS 是 Hypermedia as the Engine of Application State 的缩写。超媒体指的是包含指向其他媒体(如图像、视频和文本)的链接的内容。它是 REST 应用程序的一个组成部分,将其与其他网络架构区分开。使用 HATEOAS,客户端通过超媒体从网络应用程序中获取动态信息,应用服务器通过超媒体提供信息。
Spring-HATEOAS
Spring-HATEOAS 是一组 API。我们可以在使用 Spring MVC 时,使用这些 API 创建遵循 HATEOAS 原则的 REST 表示。
在 Spring HATEOAS 项目中,我们不需要使用 Servlet 上下文,并且也不需要将路径变量连接到基本 URI。取而代之,Spring HATEOAS 提供了三个抽象用于创建 URI:ControllerLinkBuilder、Link 和 ResourceSupport。我们可以使用这些抽象来创建与资源表示相关联的元数据。
Features
- 它支持类似 HAL 的超媒体格式。
- 它提供了创建指向 MVC 控制器方法的链接的 Link builder API。
- 它提供了链接、资源表示模型的 Model classes。
Spring Boot 执行以下任务:
- 配置 HAL 支持
- 注册支持实体链接
- 配置消息转换器支持
假设我们请求了一个 GET 请求,如 localhost:8080/users/1,它会返回用户 ID 为 1 的详细信息。除此之外,它还返回一个名为 link 的字段,其中包含一个指向所有用户的链接(localhost:8080/users),以便消费者可以检索所有用户。这个概念就是 HATEOAS。
让我们在项目中实现 HATEOAS。
步骤 1: 打开 pom.xml 文件并添加 spring-boot-starter-hateoas 依赖。
<dependency>d
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
步骤 2: 打开 UserResource.java 文件,复制 retrieveUser() 方法。
步骤 3: 粘贴该方法并进行以下更改:
- 创建 Resource 类的构造函数。
Resource<User> resource = new Resource<User>(User)
请注意,导入 org.springframework.hateoas 包中的 Resource 类。
- 使用 ControllerLinkBuilder 类添加链接,以检索所有用户。它使我们能够从方法中创建链接。
- 导入 ControllerLinkBuilder。
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.
- 使用 ControllerLinkBuilder 类的 linkTo() 方法。它使用给定控制器类上注释的映射创建一个新的 ControllerLinkBuilder 实例。
ControllerLinkBuilder linkTo=linkTo(methodOn(this.getClass().retrieveAllUsers());
其中,methodOn() 是 DummyInvocationUtils.methodOn(class, Object) 的包装器,以便在静态导入 ControllerLinkBuilder 时可用。
- 将此链接添加到资源中,并指定在 HATEOAS 中要使用的名称。
resource.add(linkTo.withRel("all-users"));
withRel(String rel) 是一种方法,用于使用当前构建器实例创建由给定的 rel 关联构建的链接。rel 参数不能为空。
- 将返回类型从用户更改为 Resource,并将方法的返回类型更改为 Resource。
经过以上更改,UserResource.java 文件如下所示:
package cn.javatiku.server.main.user;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
import java.net.URI;
import java.util.List;
import javax.validation.Valid;
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.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
@RestController
public class UserResource
{
@Autowired
private UserDaoService service;
@GetMapping("/users")
public List<User> retriveAllUsers()
{
return service.findAll();
}
@GetMapping("/users/{id}")
public Resource<User> retriveUser(@PathVariable int id)
{
User user= service.findOne(id);
if(user==null)
//runtime exception
throw new UserNotFoundException("id: "+ id);
//"all-users", SERVER_PATH + "/users"
//retrieveAllUsers
Resource<User> resource=new Resource<User>(user); //constructor of Resource class
//add link to retrieve all the users
ControllerLinkBuilder linkTo=linkTo(methodOn(this.getClass()).retriveAllUsers());
resource.add(linkTo.withRel("all-users"));
return resource;
}
//method that delete a user resource
@DeleteMapping("/users/{id}")
public void deleteUser(@PathVariable int id)
{
User user= service.deleteById(id);
if(user==null)
//runtime exception
throw new UserNotFoundException("id: "+ id);
}
//method that posts a new user detail and returns the status of the user resource
@PostMapping("/users")
public ResponseEntity<Object> createUser(@Valid @RequestBody User user)
{
User sevedUser=service.save(user);
URI location=ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(sevedUser.getId()).toUri();
return ResponseEntity.created(location).build();
}
}
步骤 4: 打开 REST 客户端 Postman,发送一个 GET 请求。
在这里,我们可以看到它返回用户以及一个名为 all-users 的链接,以便访问所有用户。现在点击该链接并再次发送 GET 请求。它返回所有用户的列表,如下图所示。