这篇文章将会引导你创建restful风格的后端服务来访问数据。
What you’ll build
接下来将会创建一个Spring应用程序, 来从数据库中以rest风格的方式存取一个Person
对象。Spring Data REST
同时具有 Spring HATEOAS 和 Spring Data JPA 的 特性。
Spring Data REST also supports Spring Data Neo4j, Spring Data Gemfire and Spring Data MongoDB as backend data stores, but those are not part of this guide.
What you’ll need
- About 15 minutes
- A favorite text editor or IDE
- JDK 1.8 or later
- Gradle 2.3+ or Maven 3.0+
- You can also import the code straight into your IDE:
- Spring Tool Suite (STS)
- IntelliJ IDEA
Build with maven
创建下述目录结构:
└── src
└── main
└── java
└── hello
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-accessing-data-rest</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
Spring Boot Maven plugin
提供了很多便利的特性。
- 它 会收集
classPath
下 所有的jar, 然后构建成一个jar, 方便了运行spring-boot
程序和做服务迁移 - 它会自动查找
public static void main()
代码段, 作为 程序的入口。 它提供对内置依赖的解析, 为依赖设置版本号。你可以在
Spring-boot
可选的依赖版本集中覆写指定版本号。Create a domain object
src/main/java/hello/Person.java
package hello;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
这个Person
有firstName
、 lastName
, 还有id
已经配置为自动生成 , 没必要去关注它。
Create a Person repository
创建一个简单的 仓库:
src/main/java/hello/PersonRepository.java
package hello;
import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(collectionResourceRel = "people", path = "people")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
List<Person> findByLastName(@Param("name") String name);
}
这个仓库是一个接口, 能够让你执行有关Person
的各种各样的操作,且必须继承 Spring Data Commons
下的
PagingAndSortingRepository
类, 在运行时 Spring
会自动创建接口的实现, 使用@RepositoryRestResource
注解来创建Spring-mvc
路由映射。
@RepositoryRestResource 作为一个仓库被暴露, 并不是必须加的 注解, 他仅仅用来指定导出到 一些细节(如果不想采取默认的导出方式【/persons】)
至此我们定义了一个客户端的查询来获取一系列Person
, 接下来我们看看如何运行。
Make the application executable
使用Spring-boot
内嵌的tomcat
运行。 首先创建一个Application.java
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
是一个很方便的注解, 包含了以下注解特性:
- @Configuration 标志这个类是一个配置类, 为
application context
提供bean
定义 - @EnableAutoConfiguration 自动根据
classPath
的设置, 载入所需的bean
和属性配置。 - 自动激活
@EnableWebMvc
@ComponentScan 扫描
hello
包下的其它components
,configurations
, andservices
andcontrollers
SpringApplication.run()
方法来启动应用, 做到了0 xml配置。纯java 构建web应用。Spring-boot
会创建PersonRepository
具体的实现。Spring Data REST
构建与Sping-Mvc
之上, 它创建了一系列SpringMvc 的controllers
集合、JSON converters
还有其他的提供RESTful
后端服务的 所需的bean
, 这些组件和Spring Data JPA
联系在一块(使用Spring Boot
全自动配置), 如果你想关注是如何工作的, 请查看RepositoryRestMvcConfiguration
的实现。Build an executable JAR
./mvnw clean package
java -jar target/gs-accessing-data-rest-0.1.0.jar
Test the application
用强大的curl
命令来mock
我们的restful
服务。
$ curl http://localhost:8080
{
"_links" : {
"people" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
}
}
}
从href
中我们看到, 我们可以通过http://localhost:8080/people
去定位一些Person
还可以传递一些查询条件: 如: page
、 size
、sort
。
Spring-Data-Rest 使用 HAL format 作为Json输出。 links结点下会链接一些相邻的数据(有推荐、引导访问某些数据的含义)
$ curl http://localhost:8080/people
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/people/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}
可以看到现在没有查出来任何数据。我们来创建
一些Person
。
$ curl -i -X POST -H "Content-Type:application/json" -d "{ \"firstName\" : \"Frodo\", \"lastName\" : \"Baggins\" }" http://localhost:8080/people
HTTP/1.1 201 Created
Server: Apache-Coyote/1.1
Location: http://localhost:8080/people/1
Content-Length: 0
Date: Wed, 26 Feb 2014 20:26:55 GMT
-i
确保你能够看到包含响应头的响应消息-X POST
标志这是一个POST
请求
-H "Content-Type:application/json"
设置content -type
-d "{ \"firstName\" : \"Frodo\", \"lastName\" : \"Baggins\" }"
body体的要post的 内容
Notice how the previous POST operation includes a Location header. This contains the URI of the newly created resource. Spring Data REST also has two methods on RepositoryRestConfiguration.setReturnBodyOnCreate(…) and setReturnBodyOnUpdate(…) which you can use to configure the framework to immediately return the representation of the resource just created. RepositoryRestConfiguration.setReturnBodyForPutAndPost(…) is a short cut method to enable representation responses for creates and updates.
至此, 我们能够查询所有的人。
$ curl http://localhost:8080/people
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/people/search"
}
},
"_embedded" : {
"persons" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
你也可以直接可以访问单条记录:
$ curl http://localhost:8080/people/1
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
在这个向导中只包含一个实体, 在一个更大的系统中, 实体之间有着复杂的联系。Spring Data REST
将会展示一些额外的连接, 导航到其它数据。
查看所有可能的客户端查询方式:
$ curl http://localhost:8080/people/search
{
"_links" : {
"findByLastName" : {
"href" : "http://localhost:8080/people/search/findByLastName{?name}",
"templated" : true
}
}
}
使用findByLastName
$ curl http://localhost:8080/people/search/findByLastName?name=Baggins
{
"_embedded" : {
"persons" : [ {
"firstName" : "Frodo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
} ]
}
}
PUT
、PATCH
、DELETE
样例:
$ curl -X PUT -H "Content-Type:application/json" -d "{ \"firstName\": \"Bilbo\", \"lastName\": \"Baggins\" }" http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
"firstName" : "Bilbo",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
$ curl -X PATCH -H "Content-Type:application/json" -d "{ \"firstName\": \"Bilbo Jr.\" }" http://localhost:8080/people/1
$ curl http://localhost:8080/people/1
{
"firstName" : "Bilbo Jr.",
"lastName" : "Baggins",
"_links" : {
"self" : {
"href" : "http://localhost:8080/people/1"
}
}
}
PUT replaces an entire record. Fields not supplied will be replaced with null. PATCH can be used to update a subset of items.
$ curl -X DELETE http://localhost:8080/people/1
$ curl http://localhost:8080/people
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/people{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/people/search"
}
},
"page" : {
"size" : 20,
"totalElements" : 0,
"totalPages" : 0,
"number" : 0
}
}