SpringBoot使用Spring Data REST快速構建restful應用

本篇要點

  • Spring Data REST的基本介紹。
  • SpringBoot快速構建restful風格接口。

Spring Data REST概述

REST Web服務已經成爲Web上應用程序集成的第一大手段。 REST的核心是定義一個包含與客戶端進行交互資源的系統。 這些資源以超媒體驅動的方式實現。html

Spring MVC和Spring WebFlux各自提供了構建REST服務的堅實基礎。 可是,即便爲multi-domain對象系統實現最簡單的REST Web服務原則也可能很繁瑣,而且會致使大量樣板代碼。前端

Spring Data REST旨在解決這個問題,它創建在Spring Data存儲庫之上,並自動將其導出爲REST資源,客戶端能夠輕鬆查詢並調用存儲庫自己暴露出來的接口。java

SpringBoot快速構建restful風格接口

SpringBoot構建Spring Data REST是至關方便的,由於自動化配置的存在,spring-boot-starter-data-rest可讓你不須要寫多少代碼,就能輕鬆構建一套完整的rest應用。mysql

除此以外,你須要引入數據存儲的依賴,它支持SpringData JPA、Spring Data MongoDB等,這裏就使用JPA啦。正好咱們前幾篇介紹過JPA的簡單使用:SpringBoot整合Spring Data JPAweb

建立項目,導入依賴

<!--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,啓動項目,先把表生成了再說。spring

啓動項目,咱們就會發現JPA已經爲咱們將表結構建立完成,而且,一個基於Restful風格的增刪改查應用也已誕生,咱們可使用接口測試工具,進行測試。sql

測試Restful接口

默認的請求路徑是 類名首字母小寫+後綴s,這裏就是users。json

測試添加功能

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

添加成功以後,返回信息以下:springboot

{
  "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的信息改成傳入信息,並返回更新後的信息。restful

{
  "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 更新成功時是否返回更新記錄

參考閱讀

相關文章
相關標籤/搜索