SpringBoot--构建RESTful服务详解

REST简介

REST(Representational State Transfer)是一种Web软件架构风格,它是一种风格,而不是标准,匹配或兼容这种架构风格的网络服务称为REST服务。REST服务简洁并且有层次,REST通常基于HTTP、URI和XML以及HTML这些现有的广泛流行的协议和标准。

在REST中,资源是由URI来指定的,对资源的增删改查操作可以通过HTTP协议提供的GET、POST、PUT、DELETE等方法实现。使用REST可以更高效地利用缓存来提高响应速度,同时REST中的通信会话状态由客户端来维护,这可以让不同的服务器处理一系列请求中的不同请求,进而提高服务器的扩展性。在前后端分离项目中,一个设计良好的Web软件架构必然要满足REST风格。

在SpringMVC框架中,开发者可以通过@RestController注解开发一个RESTful服务,不过,SpringBoot对此提供了自动化配置方案,开发者只需要添加相关依赖就能快速构建一个RESTful服务。

JPA实现REST

1. 创建项目,添加如下依赖:

		 <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

在application.yml配置:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: 123456
    url: jdbc:mysql:///springboot
  jpa:
    hibernate:
      ddl-auto: update
    database: mysql
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL57Dialect
    show-sql: true

2. 创建实体类:

@Entity(name = "t_book")
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private String author;
    //省略getter和setter
}

3. 创建BookRepository:
继承JpaRepository,JpaRepository中默认提供了一些基本的操作方法:

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

4. 测试:
使用Postman工具进行测试:

  • 添加数据

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

添加一条数据:发起一个post请求,请求地址为http://localhost:8080/books
在这里插入图片描述
当添加成功后,服务端会返回刚刚添加成功的数据的基本信息以及浏览器地址。

  • 查询数据

查询是GET请求,分页查询请求路径为/books,请求url如下:

http://localhost:8080/books

分页查询请求默认每页记录是20条,页数为0(从0开始计算):
在这里插入图片描述
在这里插入图片描述

如果想要修改请求页码和每页记录数,只需要在请求地址中携带上相关参数即可,例如查询第2页数据并且每页记录数为3:

http://localhost:8080/books?page=1&size=3

如果想要排序,例如想查询第2页数据,每页记录数为3,并且按照id倒序排列,请求url如下:

http://localhost:8080/books?page=1&size=3&sort-id,desc

如果按照id查询,只需要在/books后面追加上id即可,例如查询id为1的book,如下图:
在这里插入图片描述

  • 修改数据

发送PUT请求可以实现对数据的修改,对数据的修改是通过id进行的,因此请求路径中要有id。

例如如下请求路径表示修改id为2的记录,具体的修改内容在请求体中:

http://localhost:8080/books/2

在这里插入图片描述

  • 删除数据

发送DELETE请求可以实现对数据的删除操作,例如删除id为1的记录,请求URL如下:

http://localhost:8080/books/1

在这里插入图片描述
DELETE请求没有返回值,上面这个请求发送成功后,id为1的记录就被删除了。

自定义请求路径

默认情况下,请求路径都是实体类名小写加s,如果开发者想对请求路径进行重定义,通过@RepositoryRestResource注解即可实现,下面的案例只需在BookRepository上面添加@RepositoryRestResource注解即可:

  • @RepositoryRestResource注解的path属性表示将所有请求路径中的books都修改为bs,如http://localhost:8080/bs;
  • collectionResourceRel属性表示将返回的JSON集合中book集合的key修改为bs;
  • itemResourceRel表示将返回的JSON集合中的单个book的key修改为b

在这里插入图片描述

自定义查询方法

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

@RepositoryRestResource(path = "bs", collectionResourceRel = "bs", itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book, Integer> {

	/*
		如果不添加2RestResource 调用路径为 http://localhost:8080/bs/search/findByAuthorContains?author=鲁迅
		如果需要对查询路径自定义,则加上@RestResource注解,下面的访问路径就是:http://localhost:8080/bs/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);
}
  • 自定义查询只需要在BookRepository中定义相关查询方法即可,方法定义好之后可以不添加@RestResource注解,默认路径就是方法名。
  • 可以直接访问http://localhost:8080/bs/search路径查看该实体类暴露出来哪些查询方法,默认情况下,在查询方法展示时使用的路径是方法名,通过@RestResource注解中的rel属性可以对这里的路径进行重定义:

在这里插入图片描述

隐藏方法

默认情况下,凡事继承了Repository接口的类都会被暴露出来,即开发者可执行基本的增删改查方法。

如果开发这继承了Repository但是又不想暴露相关操作,做如下配置即可:

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

将@RepositoryRestResource注解中的exported属性置为false之后,则上面定义的增删改查接口都会失效,BookRepository类中定义的相关方法也会失效。

若只是单纯地不想暴露某个方法,则在方法上进行配置即可,例如如果想屏蔽DELETE接口,做如下配置即可:

@RepositoryRestResource(path = "bs", collectionResourceRel = "bs", itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book, Integer> {
	@Override
	@RestResource(exported = false)
	void deleteById(Integer integer);
}

//@RestResource注解的exported属性默认为true,将之置为false即可。

配置CORS

两种方式:

  • 全局配置
  • @CrossOrigin注解

全局配置在这里依然生效,但是默认的RESTful工程不需要我们自己提供Controller,所以添加在Controller的方法上的注解可以直接写在BookRepository上:

@CrossOrigin
@RepositoryRestResource(path = "bs", collectionResourceRel = "bs", itemResourceRel = "b")
public interface BookRepository extends JpaRepository<Book, Integer> {

    @RestResource(path = "author", rel = "author")
    List<Book> findByAuthorContains(@Param("author") String author);

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

此时,BookRepository中的所有方法都支持跨域。如果只需要某一个方法支持跨域,那么将@CrossOrigin注解添加到某一个方法上即可。

配置文件

可以在application.properties中配置一些常用属性:

#每页默认记录数,默认值为20
spring.data.rest.default-page-size=2
#分页查询页码参数名,默认值为page
spring.data.rest.page-param-name=page
#分页查询记录数参数名,默认值为size
spring.data.rest.limit-param-name=size
#分页查询排序参数名,默认值为sort
spring.data.rest.sort-param-name=sort
#base-path表示给所有请求路径都加上前缀
spring.data.rest.base-path=/api
#添加成功时是否返回添加内容
spring.data.rest.return-body-on-create-true
#更新成功时是否返回更新内容
spring.data.rest.return-body-on-update=true

配置类

配置类的优先级高于配置文件:

@Configuration
public class RestConfig implements RepositoryRestConfigurer {
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setDefaultPageSize(2)
                .setPageParamName("page")
                .setLimitParamName("size")
                .setSortParamName("sort")
                .setBasePath("/api")
                .setReturnBodyOnCreate(true)
                .setReturnBodyOnUpdate(true);
    }
}
发布了716 篇原创文章 · 获赞 2079 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/104177059