SpringBoot 学习笔记_构建 RESTful 服务

SpringBoot 学习笔记_构建 RESTful 服务

声明:

本次学习参考 《SpringBoot + Vue 开发实战》 · 王松(著) 一书。

本文的目的是记录我学习的过程和遇到的一些问题以及解决办法,其内容主要来源于原书。

如有侵权,请联系我删除

SpringBoot 构建 RESTful 服务

REST(Representational State Transfer) 是一种 Web 软件架构风格,它是一种风格,而不是标准,匹配或兼容这种架构风格的网络服务成为 REST 服务。

REST 服务简洁并且有层次,REST 通常基于 HTTP、URI 和 XML 以及 HTML 这些现有的广泛流行的协议和标准。在 REST 中,资源由 URI 来指定,最资源的增删改查操作可以通过 HTTP 协议提供的 GET、POST、PUT、DELETE 等方法实现。

使用 REST 可以更高效的利用缓存来提高响应速度,同时 REST 中的通信会话状态由客户端来维护,可以让不同的服务器处理一系列请求中的不同请求,进而提高服务器的扩展性。

Spring MVC 框架中,开发者可以通过 @RestController 注解开发一个 RESTful 服务,不过,SpringBoot 对此提供了自动化配置方案。

JPA 实现 REST

SpringBoot 中,使用 Spring Data JPA 和 Spring Data Rest 可以快速开发出一个 RESTful 应用。

环境搭建
  • 创建 SpringBoot 项目,添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.9</version>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 配置数据库基本连接 (application.properties)

    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.url=jdbc:mysql://localhost:3306/jpa_restful?serverTimezone=GMT
    spring.jpa.hibernate.ddl-auto=update
    spring.jpa.database=mysql
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
    spring.jpa.show-sql=true
    
  • 创建实体类

    @Entity(name = "t_book")
    public class Book {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Integer id;
    
        private String name;
        private String author;
    
        /*  Getter & Setter */
    }
    
  • 创建 BookRepository 接口继承 JpaRepository

    public interface BookRepository extends JpaRepository<Book, Integer> {
    
    }
    

    JpaRepository 接口中默认提供了一些基本的操作方法: findAll、findAllById、saveAll、flush、deleteInBatch、getOne 等

  • 测试

    RESTful 服务创建成功后,默认的请求路径是实体类名小写再加上 s 后缀。

    • 新增(POST 请求)
      选择 POST 请求,输入请求连接 http://localhost:8080/books,在 Body 中输入参数,选择 raw 数据类型, 格式选择 JSON,输入 {"name": "三国演义", "author": "罗贯中"}

      post

    • 查询(GET 请求)
      选择 GET 请求,输入请求连接

      • 默认分页: http://localhost:8080/books
      • 指定分页: http://localhost:8080/books?page=1&size=3
      • 默认参数 id: http://localhost:8080/books/1
      • 支持排序: http://localhost:8080/books?page=0&size=20&sort=id,desc

      get

    • 修改(PUT 请求)

      选择 PUT 请求,输入请求连接 http://localhost:8080/books/5 ,在 Body 中输入参数,选择 raw, 格式选择 JSON,输入 {"name": "朝花夕拾", "author": "鲁迅"}

    • 删除(DELETE 请求)
      选择 DELETE 请求,输入请求连接 http://localhost:8080/books/5

自定义请求路径

默认情况下,请求路径都是实体类名 + s,如果想对请求路径进行重定义,可以通过 @RepositoryResource 注解实现。

/**
 * path: 表示所有请求路径中默认为实体类 + s 部分。 http://localhost:8080/bs
 * collectionResourceRel: 表示返回 JSON 集合中实体类集合的 key
 * itemResourceRel: 表示返回 JSON 集合中的单个实体类的 key
 */
@RepositoryRestResource(path = "bs", collectionResourceRel = "bs", itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book, Integer> {

}
自定义查询方法

默认的查询方法支持分页查询、排序查询和 id 查询。如果想要按照某个属性查询,只需要在 BookRepository 中定义相关方法并暴露出去即可

public interface BookRepository extends JpaRepository<Book, Integer> {

    /**
     * 默认的查询方法支持分页查询、排序查询和 id 查询。
     * 如果想要按照某个属性查询,只需要在 `BookRepository` 中定义相关方法并暴露出去即可
     *
     * 自定义查询方法
     *      可以直接通过 http://localhost:8080/books/search 查看该实体类暴露了哪些查询方法
     */

    // 默认查询路径为 http://localhost:8080/books/search/findByAuthorContains?author=鲁迅
    // RestResource 注解可以自定义查询路径 http://localhost:8080/books/search/author?author=鲁迅
    @RestResource(path = "author", rel = "author")
    List<Book> findByAuthorContains(@Param("author") String author);

    @RestResource(path = "name", rel = "name")
    Book findByNameEquals(@Param("name") String name);
}

隐藏方法

默认情况下,继承了 Repository 接口的类都会被暴露,如果继承了该接口,又不想暴露相关操作,可以如下配置

@RepositoryRestResource(exported = false)
public interface BookRepository extends JpaRepository<Book, Integer> {

}

设置 exported 属性的值为 false,则 BookRepository 类中定义的方法包含其继承过来的方法都会失效。

如果只是不想暴露某一个方法,也可以直接在具体方法上进行配置 @RestResource(exported=false)

//@RepositoryRestResource(exported = false)
public interface BookRepository extends JpaRepository<Book, Integer> {
   
    @RestResource(path = "author", rel = "author", exported=false)
    List<Book> findByAuthorContains(@Param("author") String author);

    @RestResource(path = "name", rel = "name")
    Book findByNameEquals(@Param("name") String name);

    @Override
    @RestResource(exported=false)
    void deleteById(Integer id);
}
配置 CORS

SpringBoot 中 CORS 的配置主要由两种方式:全局配置和具体配置。

默认的 RESTful 工程不需要自己提供 Controller,所以本应该配置在 Controller 上的注解可以直接写在 BookRepository

@CrossOrigin
public interface BookRepository extends JpaRepository<Book, Integer> {
   
    @RestResource(path = "author", rel = "author", exported=false)
    List<Book> findByAuthorContains(@Param("author") String author);

    @RestResource(path = "name", rel = "name")
    Book findByNameEquals(@Param("name") String name);

    @Override
    @RestResource(exported=false)
    void deleteById(Integer id);
}
其他常用配置
  • application.properties

    ### 其他常用配置 ###
    # 每页默认记录数。默认 20
    spring.data.rest.default-page-size=20
    # 分页查询页码出参数名。默认 page
    spring.data.rest.page-param-name=page
    # 分页查询记录数参数名。默认 size
    spring.data.rest.limit-param-name=size
    # 分页查询排序参数名。默认 sort
    spring.data.rest.sort-param-name=sort
    # 所有请求的路径的前缀。默认 空
    #spring.data.rest.base-path=/api
    # 添加成功时是否返回添加内容
    spring.data.rest.return-body-on-create=true
    # 更新成功时是否返回更新内容
    spring.data.rest.return-body-on-update=true
    
  • RestConfig.java

    也可以在 java 代码中创建配置类进行配置,且优先级高于 application.properties

    /**
     * 新建配置类
     */
    @Configuration
    public class RestConfig implements RepositoryRestConfigurer {
        @Override
        public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    
            config.setDefaultPageSize(2)
                    .setPageParamName("page")
                    .setLimitParamName("size")
                    .setSortParamName("sort");
        }
    }
    

    原书中是继承 RepositoryRestConfigurerAdapter 类,但 RepositoryRestConfigurerAdapter 已被标记为过时。

    修改为实现 RepositoryRestConfigurer 接口。

MongoDB 实现 REST

SpringBoot 中,使用 Spring Data MongoDB 和 Spring Data Rest 可以快速开发出一个 RESTful 应用。

环境搭建
  • 创建 SpringBoot 项目,添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    
  • 配置数据库基本连接 (application.properties)

    spring.data.mongodb.authentication-database=test
    spring.data.mongodb.database=test
    spring.data.mongodb.username=sang
    spring.datasource.password=123456
    spring.data.mongodb.host=localhost
    spring.data.mongodb.port=27017
    
  • 创建实体类

    public class Book {
        private Integer id;
        private String name ;
        private String author;
        /* Getter & Setter */
    }
    
  • 创建 BookRepository 接口继承 JpaRepository

    public interface BookRepository extends MongoRepository<Book, Integer> {
    
    }
    
  • 测试

    同上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HolaSecurity

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值