zoukankan      html  css  js  c++  java
  • RestFul && HATEOAS && Spring-Data-Rest介绍

    1、什么是RestFul

    经常上网的同学会发现,现代软件的一个重要趋势就是互联网化,几乎没有一款软件是纯粹的单机版了。通常的情况下,软件管理着服务器的资源以及这些资源的状态变化,用户通过在浏览器输入http地址,能够对服务器的资源进行各种处理。这就要求软件提供一组访问接口,使得软件能够和互联网的http访问格式完美对接。REST对这种借口的一种约束标准。(这里我们所说的软件,最常见的形式就是一个网站系统)

    REST 是 Representational state transfer 的缩写,翻译过来的意思是表达性状态转换,REST 这个词是2000 年 Roy Fielding 在其博士论文中创造出来的。REST 是一种架构风格,它包含了一个分布式超文本系统中对于组件、连接器和数据的约束。REST 是作为互联网自身架构的抽象而出现的,其关键在于所定义的架构上的各种约束。只有满足这些约束,才能称之为符合 REST 架构风格,即所谓的“RESTful”服务

    这里我们不对这些约束进行描述。详细内容可以参考IBM的一篇文章(http://www.ibm.com/developerworks/cn/java/j-lo-SpringHATEOAS/)

    2、HATEOAS

    HATEOAS(Hypermedia as the engine of application state)是 REST 架构风格中最复杂的约束,也是构建成熟 REST 服务的核心。它的重要性在于打破了客户端和服务器之间严格的契约,使得客户端可以更加智能和自适应,而 REST 服务本身的演化和更新也变得更加容易。

    上面这段话其实很难理解。首先hateoas这个单词就很难记住,我的方法是先记住hate(恨之入骨),然后再加上oas。经过一点实践,我认为这里的自适应,指得是服务器返回给客户端的信息中,会自动包含了客户端能够进行的操作,这样二者之间就不用通过建立一份额外的文档来约定访问的格式了。

    3、Spring HATEOAS

    Spring Hateoas,是Spring的一个子项目,Spring HATEOAS 的主要功能在于提供了简单的机制来创建这些满足HATEOAS要求的链接,并与 Spring MVC 框架有很好的结合。在实践中,我不会单独使用这个子项目,而是采用下面的方法。

    4、Spring Data REST

    Spring Data Rest也是Spring的一个子项目,它的主要功能就是把你的Spring Data Repositories以满足HATEOAS的格式暴露出去,因此你的JPA资源Repository可以用一种通用的http访问格式对你的Respository进行CRUD,而且可以省去大部分controller和services的逻辑,因为Spring Data REST已经为你都做好了,你只需要保证你的http访问格式正确即可,是不是很酷?(关于JPA,也是一个比较常见的概念,我会在另外一篇博客里面讲一下我的理解)

    还有更酷的一点,我们可以对Repositories对外暴露的格式和内容进行个性化的定制,这属于稍微高级一点的内容,我们这里不涉及。

    现在我们就可以看看默认的Spring Data Test对访问格式是如何定义的,当然,最权威的还是官方的文档,地址在这里(http://docs.spring.io/spring-data/rest/docs/2.4.0.RELEASE/reference/html/)

    下面是我用Spring Data Rest提供的工具The HAL Browser得到一些结果(关于该工具的使用,请参考http://docs.spring.io/spring-data/rest/docs/2.4.0.RELEASE/reference/html/#_the_hal_browser)。

    再补充一下:我对默认的配置做了一点改动,这样我们在返回的json格式的结构体中会包含id。

    public class AppConfig extends RepositoryRestMvcConfiguration {
      @Override
        public RepositoryRestConfiguration config() {
            RepositoryRestConfiguration config = super.config();
            config.setDefaultPageSize(6);/*设置默认页大小*/
            //设置返回的json Body中显示id
            config.exposeIdsFor(User.class);
         //config.setReturnBodyOnCreate(true);设置创建成果后返回创建成果的结果,实际上这样做没有什么意义
    return config; } }

    4.1获取集合资源

    General
    Remote Address:[::1]:8080
    Request URL:http://localhost:8080/traveller/users?page=0
    Request Method:GET
    Status Code:200 OK
    
    Response Headers
    Content-Type:application/json;charset=UTF-8
    Date:Wed, 30 Sep 2015 17:27:07 GMT
    Server:Apache-Coyote/1.1
    Transfer-Encoding:chunked

    //下面是返回的JSON格式体
    {
      "_links": {
        "self": {
          "href": "http://localhost:8080/traveller/users{?page,size,sort}",
          "templated": true
        },
        "next": {
          "href": "http://localhost:8080/traveller/users?page=1&size=6{&sort}",
          "templated": true
        },
        "search": {
          "href": "http://localhost:8080/traveller/users/search"
        }
      },
      "_embedded": {
        "users": [
          {
            "id": 1,
            "birthdate": "2015-09-16",
            "country": 0,
            "email": "stive.jobs@apple.com",
            "enabled": true,
            "info": null,
            "name": "JOBS",
            "password": "steve",
            "phone": "0033 1 23 45 67 89",
            "picture": "1.jpg",
            "gender": 0,
            "regdate": "2015-09-25T02:54:01.000+0000",
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/1"
              }
            }
          },
          {
            "id": 2,
            "birthdate": null,
            "country": 0,
            "email": "bill.gates@microsoft.com",
            "enabled": true,
            "info": null,
            "name": "GATES",
            "password": "bill",
            "phone": "0033 1 23 45 67 89",
            "picture": "2.jpg",
            "gender": 0,
            "regdate": null,
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/2"
              }
            }
          },
          {
            "id": 3,
            "birthdate": null,
            "country": 0,
            "email": "mark.zuckerberg@facebook.com",
            "enabled": true,
            "info": null,
            "name": "ZUCKERBERG",
            "password": "zuckerberg",
            "phone": "0033 1 23 45 67 89",
            "picture": "3.jpg",
            "gender": 0,
            "regdate": null,
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/3"
              }
            }
          },
          {
            "id": 4,
            "birthdate": null,
            "country": 0,
            "email": "tim.cook@apple.com",
            "enabled": true,
            "info": null,
            "name": "COOK",
            "password": "cook",
            "phone": "0033 1 23 45 67 89",
            "picture": "4.jpg",
            "gender": 0,
            "regdate": null,
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/4"
              }
            }
          },
          {
            "id": 5,
            "birthdate": null,
            "country": 0,
            "email": "larry.page@gmail.com",
            "enabled": true,
            "info": null,
            "name": "Page",
            "password": "page",
            "phone": "0033 1 23 45 67 89",
            "picture": "5.jpg",
            "gender": 0,
            "regdate": null,
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/5"
              }
            }
          },
          {
            "id": 6,
            "birthdate": null,
            "country": 0,
            "email": "sergey.brin@gmail.com",
            "enabled": true,
            "info": null,
            "name": "Brin",
            "password": "brin",
            "phone": "0033 1 23 45 67 89",
            "picture": "6.jpg",
            "gender": 0,
            "regdate": null,
            "_links": {
              "self": {
                "href": "http://localhost:8080/traveller/users/6"
              }
            }
          }
        ]
      },
      "page": {
        "size": 6,
        "totalElements": 25,
        "totalPages": 5,
        "number": 0
      }
    }

    4.2获取单个资源

    General
    Remote Address:[::1]:8080
    Request URL:http://localhost:8080/traveller/users/1
    Request Method:GET
    Status Code:200 OK
    
    Response Headers
    Content-Type:application/json;charset=UTF-8
    Date:Wed, 30 Sep 2015 17:35:23 GMT
    Server:Apache-Coyote/1.1
    Transfer-Encoding:chunked
    {
      "id": 1,
      "birthdate": "2015-09-16",
      "country": 0,
      "email": "stive.jobs@apple.com",
      "enabled": true,
      "info": null,
      "name": "JOBS",
      "password": "steve",
      "phone": "0033 1 23 45 67 89",
      "picture": "1.jpg",
      "gender": 0,
      "regdate": "2015-09-25T02:54:01.000+0000",
      "_links": {
        "self": {
          "href": "http://localhost:8080/traveller/users/1"
        }
      }
    }

     4.2保存单个资源

    General
    Remote Address:[::1]:8080
    Request URL:http://localhost:8080/traveller/users
    Request Method:POST
    Status Code:201 Created
    
    Response Headers
    Content-Length:0
    Date:Wed, 30 Sep 2015 17:40:00 GMT
    Location:http://localhost:8080/traveller/users/30
    Server:Apache-Coyote/1.1
    
    无其他返回值
  • 相关阅读:
    summary
    谷歌浏览器Software Reporter Tool长时间占用CPU解决办法
    进栈 出栈 标准用法
    C语言保证,0永远不是有效的数据地址,因此,返回址0可用来表示发生的异常事件
    寄存器是内存阶层中的最顶端,也是系统获得操作资料的最快速途径。 存于寄存器内的地址可用来指向内存的某个位置,即寻址
    对内存分配的理解 自动变量 局部变量 临时变量 外部变量 字符串长度 C语言可以看成由一些列的外部对象构成
    ORM Active Record Data Mapper
    summary
    c预处理器
    #include<stdio.h> #include "stdio.h"
  • 原文地址:https://www.cnblogs.com/mingziday/p/4850544.html
Copyright © 2011-2022 走看看