美文网首页
Spring HATEOAS

Spring HATEOAS

作者: 宋冉_ | 来源:发表于2019-03-30 19:59 被阅读0次

    一.简介

            Spring HATEOAS的目标是解决两个问题:link creation(创建链接)及representation assembly(集合表述)。

    二.创建链接

            HATEOAS的核心是链接。链接的存在使得客户端可以动态发现其所能执行的动作。

    HATEOAS生成链接的几种方式:

    ① 静态生成链接

            Spring HATEOAS使用 org.springframework.hateoas.Link 类来表示链接。可以继承自 Spring HATEOAS 提供的 org.springframework.hateoas.Resource 类,Resource 类提供了简单的方式来创建链接。

    Eg:

    Link link1 = new Link("http://localhost:8080/something");

    ② 动态生成链接

            在创建资源的链接时,指向单个资源的链接的href属性值是类似“http://localhost:8080/lists/1”这样的格式。而其中的“/lists”不应该是硬编码的,否则当修改了 ListRestController 类的“@RequestMapping”时,所有相关的生成链接的代码都需要进行修改。Spring HATEOAS 提供了 org.springframework.hateoas.mvc.ControllerLinkBuilder 来解决这个问题,用来根据 Spring MVC 控制器动态生成链接。

    Eg:

    //通过slash方法找到下一级,生成自身链接

    Link link = linkTo(PersonController.class).slash(person.getId()).withSelfRel();

    //如果实体类实现Identifiable接口

    Link link = linkTo(PersonController.class).slash(person).withSelfRel();

    //通过指定类的方法,生成rel为"items"的链接

    Link link = linkTo(methodOn(ItemRestController.class).readItems(listId)).withRel("items");

    ③ 通过实体类创建单个链接

            首先需要添加Maven依赖,此外还需要在控制器类中通过“@ExposesResourceFor”注解声明其所暴露的模型类,另外在 Spring 应用的配置类中需要通过“@EnableEntityLinks”注解来启用 EntityLinks 功能。

    Eg:

    <dependency>

     <groupId>org.springframework.plugin</groupId>

     <artifactId>spring-plugin-core</artifactId>

     <version>1.1.0.RELEASE</version>

    </dependency>

    @RestController

    @ExposesResourceFor(List.class)

    @RequestMapping("/lists")

    public class ListRestController {

    @Autowired

    private EntityLinks entityLinks;

    entityLinks.linkForSingleResource(List.class, 1)  

    }

            需要注意的是,为了linkForSingleResource方法可以正常工作,控制器类中需要包含访问单个资源的方法,而且其“@RequestMapping”是类似“/{id}”这样的形式。

    ④Model—>ModelResource

            继承ResourceAssemblerSupport类,并根据ModelRestController与ModelResource进行相应配置。

    //组装单个资源对象

    new ModelResourceAssembler().toResource(model);

    //组装资源对象的集合

    Resources<ModelResource> resources = new Resources<ModelResource>(new ModelResourceAssembler().toResources(models));

    二.集合表述

    ①Resource资源

            继承Resource类,在ModelResource类中可以根据实体参数进行自定义封装,并向ModelResource中添加自定义链接。

    Eg:

    public class ChartResource extends Resource {    public ChartResource(Chart chart) throws Exception {        super(chart);        Long chartId = chart.getId();         add(linkTo(methodOn(ChartRestController.class).getDimensions(chartId)).withRel("dimensions"));//维度         add(linkTo(methodOn(ChartRestController.class).getConditions(1)).withRel("conditions"));//条件    }}

    结果如下:

    "id": 1,

    "title": "房价监管",

    "_links": {

    "dimensions": {"href": "http://localhost:8088/charts/1/dimensions"}, "conditions": {"href": "http://localhost:8088/charts/1/conditions"}, "self": {"href": "http://localhost:8088/charts/1"}

    }

    ②_embedded子集合

            首先是内嵌资源在_embedded对应的哈希对象中的属性值,该属性值是由 org.springframework.hateoas.RelProvider 接口的实现来提供的。对于应用来说,只需要在内嵌资源对应的模型类中添加 org.springframework.hateoas.core.Relation 注解即可.

    @Relation(value = "list", collectionRelation = "lists")

    public class List extends AbstractEntity {

    }

    CurieProvider API

            使用URL作为链接的关系带来的问题是 URL 作为属性名称来说显得过长,而且不同关系的 URL 的大部分内容是重复的。为了解决这个问题,可以使用 Curie。简单来说,Curie 可以作为链接关系 URL 的模板。链接的关系声明时使用 Curie 的名称作为前缀,不用提供完整的 URL。应用中声明的 Curie 出现在_links 属性中。

    @Bean

    public CurieProvider curieProvider() {

    return new DefaultCurieProvider("todo",

    new UriTemplate("http://www.midgetontoes.com/todolist/rels/{rel}"));

    }

    注意:CurieProvider每个应用程序范围只能定义一个bean

    获取链接属性:

    String content = "{'_links' :  { 'foo' : { 'href' : '/foo/bar' }}}";

    LinkDiscoverer discoverer = new HalLinkDiscoverer();

    Link link = discoverer.findLinkWithRel("foo", content);

    assertThat(link.getRel(), is("foo"));

    assertThat(link.getHref(), is("/foo/bar"));

    相关文章

      网友评论

          本文标题:Spring HATEOAS

          本文链接:https://www.haomeiwen.com/subject/qpisbqtx.html