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": "罗贯中"}
-
查询(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
- 默认分页:
-
修改(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> { }
-
测试
同上