Spring MVC,REST和HATEOAS

Sin*_*hot 24 rest spring spring-mvc hateoas

我正在努力使用HATEOAS实现Spring MVC 3.x RESTful服务的正确方法.考虑以下约束:

  • 我不希望我的域实体被web/rest构造污染.
  • 我不希望我的控制器被视图构造污染.
  • 我想支持多个视图.

目前我有一个很好的组合MVC应用程序没有HATEOAS.域实体是纯POJO,没有嵌入任何视图或web/rest概念.例如:

class User {
   public String getName() {...}
   public String setName(String name) {...}
   ...
}
Run Code Online (Sandbox Code Playgroud)

我的控制器也很简单.它们提供路由和状态,并委托Spring的视图解析框架.注意我的应用程序支持JSON,XML和HTML,但没有域实体或控制器具有嵌入的视图信息:

@Controller
@RequestMapping("/users")
class UserController {

  @RequestMapping
  public ModelAndView getAllUsers() {
    List<User> users = userRepository.findAll();
    return new ModelAndView("users/index", "users", users);
  }

  @RequestMapping("/{id}")
  public ModelAndView getUser(@PathVariable Long id) {
    User user = userRepository.findById(id);
    return new ModelAndView("users/show", "user", user);
  }
}
Run Code Online (Sandbox Code Playgroud)

所以,现在我的问题 - 我不确定支持HATEOAS的干净方法.这是一个例子.假设当客户端要求JSON格式的用户时,它会出现如下:

{
  firstName: "John",
  lastName: "Smith"
}
Run Code Online (Sandbox Code Playgroud)

我们还要说当我支持HATEOAS时,我希望JSON包含一个简单的"自我"链接,然后客户端可以使用它来刷新对象,删除它或其他东西.它可能还有一个"朋友"链接,指示如何获取用户的朋友列表:

{
  firstName: "John",
  lastName: "Smith",
  links: [
    {
      rel: "self",
      ref: "http://myserver/users/1"
    },
    {
      rel: "friends",
      ref: "http://myserver/users/1/friends"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

不知何故,我想附加链接到我的对象.我觉得正确的地方是控制器层,因为控制器都知道正确的URL.另外,由于我支持多个视图,我觉得正确的做法是在转换为JSON/XML /在Spring的视图分辨率框架中的任何内容之前以某种方式装饰控制器中的域实体.一种方法可能是使用包含链接列表的通用Resource类包装有问题的POJO.一些视图调整将需要将其压缩成我想要的格式,但它的可行性.遗憾的是,嵌套资源无法以这种方式包装.其他想到的事情包括添加到ModelAndView的链接,然后自定义每个Spring的开箱即用的视图解析器,以将链接填充到生成的JSON/XML /等中.我不想要的是不断手工制作JSON/XML /等.在开发过程中来来去去,以适应各种环节.

思考?

smi*_*eej 10

在GitHub上有一个名为Spring HATEOAS的有用项目,它具有以下描述:

"这个项目提供了一些API,以便在使用Spring,尤其是Spring MVC时,轻松创建遵循HATEOAS原则的REST表示"

如果您要返回的资源类扩展了"ResourceSupport",您可以轻松地向其添加链接,并且可以使用"ControllerLinkBuilder"构建链接,例如添加自链接:

import static org.sfw.hateoas.mvc.ControllerLinkBuilder.*;

Link link = linkTo(YourController.class).slash(resource.getName()).withSelfRel();
resource.add(link);
Run Code Online (Sandbox Code Playgroud)

这是一个相当新的项目,但如果需要,可以从公共Maven仓库获得:

<dependency>
    <groupId>org.springframework.hateoas</groupId>
    <artifactId>spring-hateoas</artifactId>
    <version>0.3.0.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

如果您使用maven工件:

org.sfw.hateoas.mvc.ControllerLinkBuilder
Run Code Online (Sandbox Code Playgroud)

变为:

org.springframework.hateoas.mvc.ControllerLinkBuilder
Run Code Online (Sandbox Code Playgroud)

  • 哦,它来自Oliver Gierke,他是Spring Data的主要人物.凉. (3认同)