• SpringBoot使用Spring Data REST快速构建restful应用


    本篇要点

    • Spring Data REST的基本介绍。
    • SpringBoot快速构建restful风格接口。

    Spring Data REST概述

    REST Web服务已经成为Web上应用程序集成的第一大手段。 REST的核心是定义一个包含与客户端进行交互资源的系统。 这些资源以超媒体驱动的方式实现。

    Spring MVC和Spring WebFlux各自提供了构建REST服务的坚实基础。 但是,即使为multi-domain对象系统实现最简单的REST Web服务原则也可能很繁琐,并且会导致大量样板代码。

    Spring Data REST旨在解决这个问题,它建立在Spring Data存储库之上,并自动将其导出为REST资源,客户端可以轻松查询并调用存储库本身暴露出来的接口。

    SpringBoot快速构建restful风格接口

    SpringBoot构建Spring Data REST是相当方便的,因为自动化配置的存在,spring-boot-starter-data-rest可以让你不需要写多少代码,就能轻松构建一套完整的rest应用。

    除此之外,你需要引入数据存储的依赖,它支持SpringData JPA、Spring Data MongoDB等,这里就使用JPA啦。正好我们前几篇介绍过JPA的简单使用:SpringBoot整合Spring Data JPA

    创建项目,导入依赖

            <!--jpa-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <!--restful-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-rest</artifactId>
            </dependency>
            <!--web-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
    

    yml配置

    server:
      port: 8081
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/restful?serverTimezone=GMT%2B8
        username: root
        password: 123456
        hikari:
          maximum-pool-size: 20
          minimum-idle: 5
      jpa:
        database: mysql
        #在建表的时候,将默认的存储引擎切换为 InnoDB
        database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
        # 配置在日志中打印出执行的 SQL 语句信息。
        show-sql: true
        # 配置指明在程序启动的时候要删除并且创建实体类对应的表。
        hibernate:
          ddl-auto: update
    

    定义实体类

    @Entity(name = "t_user")
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String username;
        private String password;
    
        @Column(length = 20)
        private Integer age;
    }
    

    定义Repository接口

    public interface UserDao extends JpaRepository<User, Long> {
    }
    

    到这里为止,其实可以发现,和JPA文章没啥差异,除了多引入了一个rest依赖。ok,启动项目,先把表生成了再说。

    启动项目,我们就会发现JPA已经为我们将表结构创建完成,并且,一个基于Restful风格的增删改查应用也已诞生,我们可以使用接口测试工具,进行测试。

    测试Restful接口

    默认的请求路径是 类名首字母小写+后缀s,这里就是users。

    测试添加功能

    POST: http://localhost:8081/users
    {
        "username": "summerday",
        "password": "123456",
        "age": 18
    }
    

    添加成功之后,返回信息如下:

    {
      "username": "summerday",
      "password": "123456",
      "age": 18,
      "_links": {
        "self": {
          "href": "http://localhost:8081/users/1"
        },
        "user": {
          "href": "http://localhost:8081/users/1"
        }
      }
    }
    

    测试删除功能

    DELETE : http://localhost:8081/users/1
    // 删除成功之后返回删除的 id = 1
    

    测试修改功能

    PUT : http://localhost:8081/users/2
    {
        "username": "summerday111",
        "password": "123456111",
        "age": 181
    }
    

    同样的,修改成功,将对应id为2的信息改为传入信息,并返回更新后的信息。

    {
      "username": "summerday111",
      "password": "123456111",
      "age": 181,
      "_links": {
        "self": {
          "href": "http://localhost:8081/users/2"
        },
        "user": {
          "href": "http://localhost:8081/users/2"
        }
      }
    }
    

    测试根据id查询

    GET : http://localhost:8081/users/3
    

    测试分页查询

    GET : http://localhost:8081/users
    

    分页查询结果:

    {
      "_embedded": {
        "users": [
          {
            "username": "summerday111",
            "password": "123456111",
            "age": 181,
            "_links": {
              "self": {
                "href": "http://localhost:8081/users/2"
              },
              "user": {
                "href": "http://localhost:8081/users/2"
              }
            }
          },
          {
            "username": "summerday",
            "password": "123456",
            "age": 18,
            "_links": {
              "self": {
                "href": "http://localhost:8081/users/3"
              },
              "user": {
                "href": "http://localhost:8081/users/3"
              }
            }
          }
        ]
      },
      "_links": {
        "self": {
          "href": "http://localhost:8081/users"
        },
        "profile": {
          "href": "http://localhost:8081/profile/users"
        }
      },
      "page": {
        "size": 20,
        "totalElements": 2,
        "totalPages": 1,
        "number": 0
      }
    }
    

    测试分页+排序

    GET : http://localhost:8081/users?page=0&size=1&sort=age,desc
    

    第一页,每页size为1的记录,按age逆序。

    {
      "_embedded": {
        "users": [
          {
            "username": "summerday111",
            "password": "123456111",
            "age": 181,
            "_links": {
              "self": {
                "href": "http://localhost:8081/users/2"
              },
              "user": {
                "href": "http://localhost:8081/users/2"
              }
            }
          }
        ]
      },
      "_links": {
        "first": {
          "href": "http://localhost:8081/users?page=0&size=1&sort=age,desc"
        },
        "self": {
          "href": "http://localhost:8081/users?page=0&size=1&sort=age,desc"
        },
        "next": {
          "href": "http://localhost:8081/users?page=1&size=1&sort=age,desc"
        },
        "last": {
          "href": "http://localhost:8081/users?page=1&size=1&sort=age,desc"
        },
        "profile": {
          "href": "http://localhost:8081/profile/users"
        }
      },
      "page": {
        "size": 1,
        "totalElements": 2,
        "totalPages": 2,
        "number": 0
      }
    }
    

    定制查询

    自定义查询接口

    public interface UserDao extends JpaRepository<User, Long> {
    
        List<User> findUsersByUsernameContaining(@Param("username")String username);
    }
    

    访问:http://localhost:8081/users/search,查询自定义接口。

    {
      "_links": {
        "findUsersByUsernameContaining": {
          "href": "http://localhost:8081/users/search/findUsersByUsernameContaining{?username}",
          "templated": true
        },
        "self": {
          "href": "http://localhost:8081/users/search"
        }
      }
    }
    

    测试一下这个方法:

    GET : http://localhost:8081/users/search/findUsersByUsernameContaining?username=111
    
    {
      "_embedded": {
        "users": [
          {
            "username": "summerday111",
            "password": "123456111",
            "age": 181,
            "_links": {
              "self": {
                "href": "http://localhost:8081/users/2"
              },
              "user": {
                "href": "http://localhost:8081/users/2"
              }
            }
          }
        ]
      },
      "_links": {
        "self": {
          "href": "http://localhost:8081/users/search/findUsersByUsernameContaining?username=111"
        }
      }
    }
    

    自定义接口名

    public interface UserDao extends JpaRepository<User, Long> {
        //rel 表示接口查询中,这个方法的 key 
        //path 表示请求路径
        @RestResource(rel = "auth", path = "auth")
        User findByUsernameAndPassword(@Param("name") String username, @Param("pswd") String password);
    }
    

    继续查询自定义的接口:

        "auth": {
          "href": "http://localhost:8081/users/search/auth{?name,pswd}",
          "templated": true
        }
    

    测试一下:

    GET : http://localhost:8081/users/search/auth?name=summerday&pswd=123456
    

    设置接口对前端隐藏

        @Override
        @RestResource(exported = false)
        void deleteById(Long aLong);
    

    定义生成JSON字符串的相关信息

    @RepositoryRestResource(collectionResourceRel = "userList",itemResourceRel = "u",path = "user")
    public interface UserDao extends JpaRepository<User, Long> {
    }
    

    此时路径名为/user

    GET : http://localhost:8081/user/2
    
    {
      "username": "summerday111",
      "password": "123456111",
      "age": 181,
      "_links": {
        "self": {
          "href": "http://localhost:8081/user/2"
        },
        "u": {
          "href": "http://localhost:8081/user/2"
        }
      }
    }
    

    其他配置属性

    Spring Data REST其他可配置的属性,通过spring.data.rest.basePath=/v1的形式指定。

    属性 描述
    basePath the root URI
    defaultPageSize 每页默认size
    maxPageSize
    pageParamName 配置分页查询时页码的 key,默认是 page
    limitParamName 配置分页查询时每页查询页数的 key,默认是size
    sortParamName 配置排序参数的 key ,默认是 sort
    defaultMediaType 配置默认的媒体类型
    returnBodyOnCreate 添加成功时是否返回添加记录
    returnBodyOnUpdate 更新成功时是否返回更新记录

    参考阅读

  • 相关阅读:
    有关TSQL中的ROUND()的用法
    孤立用户
    微小的边缘原理
    分段统计查询的方法
    虎尾兰
    有规律字段的拆分
    对索引视图的限制
    金额转换为英文大写
    经典名言
    最大信息熵原理
  • 原文地址:https://www.cnblogs.com/summerday152/p/14076652.html
Copyright © 2020-2023  润新知