© 2012-2015 Original authors

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
本文档的副本可以供自己使用和发送给别人,须保证不收取任何费用,分布所在打印或电子的每个副本包含版权声明。
Table of Contents

引言(Preface)

项目元数据(Project metadata)

Due to different inception dates of individual Spring Data modules, most of them carry different major and minor version numbers. The easiest way to find compatible ones is by relying on the Spring Data Release Train BOM we ship with the compatible versions defined. In a Maven project you’d declare this dependency in the <dependencyManagement /> section of your POM:

由于单个的Spring Data模块的开始日期不同,它们大多数都有着不同的主要的和次要的版本号。让程序兼容的最简单的方法就是依靠Spring Data Release系列的BOM找到与我们兼容的版本的定义。在一个Maven项目中你会这样声明依赖项<dependencyManagement />你的POM部分:

Example 1. 使用Spring Data发布系列BOM
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-releasetrain</artifactId>
      <version>${release-train}</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

The current release train version is {releasetrainVersion}. The train names are ascending alphabetically and currently available ones are listed here. The version name follows the following pattern: ${name}-${release} where release can be one of the following:

目前发布的版本系列号为Hopper-SR2。这个系列名是根据字母顺序升序排列的,这是当前可用的列[here](https://github.com/spring-projects/spring-data-commons/wiki/Release-planning)。版本名称格式遵循下面的格式: ${name}-${release}发行时可以按照以下格式:

  • BUILD-SNAPSHOT - current snapshots

  • M1, M2 etc. - milestones

  • RC1, RC2 etc. - release candidates

  • RELEASE - GA release

  • SR1, SR2 etc. - service releases

  • BUILD-SNAPSHOT - 当前副本

  • M1, M2 etc. - 里程碑

  • RC1, RC2 etc. - 候选发布版本

  • RELEASE - 正式版

  • SR1, SR2 etc. - 服务版本

A working example of using the BOMs can be found in our Spring Data examples repository. If that’s in place declare the Spring Data modules you’d like to use without a version in the <dependencies /> block.

我们可以在这里找到一个使用BOM清单的工作示例[Spring Data examples repository](https://github.com/spring-projects/spring-data-examples/tree/master/bom)。如果在一个地方声明你想要使用没有版本号的Spring Data模块应该这样<dependencies />

Example 2. 声明一个Spring Data模块的依赖
<dependencies>
  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
  </dependency>
<dependencies>

使用Spring Boot管理依赖(Dependency management with Spring Boot)

Spring Boot already selects a very recent version of Spring Data modules for you. In case you want to upgrade to a newer version nonetheless, simply configure the property spring-data-releasetrain.version to the train name and iteration you’d like to use.

Spring Boot已经选择一个最近的版本的Spring Data。尽管如此如果你想升级到新的版本,简单配置一下属性spring-data-releasetrain.version 为 [train name and iteration](http://docs.spring.io/spring-data/rest/docs/2.5.2.RELEASE/reference/html/#dependencies.train-names)输入你想使用的版本号。

Spring Framework

The current version of Spring Data modules require Spring Framework in version {springVersion} or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended.

当前版本的Spring Data模块使用需要Spring Framewor4.2.6版本或者更高的版本。该模块也可以使用老的版本的修正版。然而,强烈推荐使用最新的版本。 :leveloffset: -1

Reference Documentation

介绍(Introduction)

REST web services have become the number one means for application integration on the web. In its core, REST defines that a system consists of resources that clients interact with. These resources are implemented in a hypermedia driven way. Spring MVC offers a solid foundation to build theses kinds of services. But implementing even the simplest tenet of REST web services for a multi-domain object system can be quite tedious and result in a lot of boilerplate code.

REST web服务已经成为了Web应用程序集成的头号手段。在它的核心中,REST定义了一个系统由客户端进行交互资源。这些资源的实现基于一个超媒体驱动的方式。Spring MVC给这类服务提供了一个坚实的基础。但是实现一个最简单的REST web服务对于多域对象系统是相当繁琐的并且结果有大量的样板代码。

Spring Data REST builds on top of Spring Data repositories and automatically exports those as REST resources. It leverages hypermedia to allow clients to find functionality exposed by the repositories and integrates these resources into related hypermedia based functionality automatically.

Spring Data REST建立在Spring Data存储库的顶部并且自动导出那些作为REST资源。它利用超媒体让客户发现公开的存储库的功能,并自动将这些资源集成到相关的超媒体作为基础的功能。

入门(Getting started)

引言(Introduction)

Spring Data REST is itself a Spring MVC application and is designed in such a way that it should integrate with your existing Spring MVC applications with very little effort. An existing (or future) layer of services can run alongside Spring Data REST with only minor considerations.

Spring Data REST本身是一个Spring MVC的应用并且它的设计就是这样一种方式用非常小的努力整合你现有的Spring MVC应用程序。一个现有的(或未来的)一层服务可以运行在Spring Data REST只需要注意一些细微之处。

添加Spring Data REST到一个Spring Boot project(Adding Spring Data REST to a Spring Boot project)

The simplest way to get to started is if you are building a Spring Boot application. That’s because Spring Data REST has both a starter as well as auto-configuration.

最简单的启动的方法就是如果你正在创建一个Spring Boot应用程序,这是因为Spring Data REST有一个启动器同时可以自动配置。

在Gradle配置Spring Boot(Spring Boot configuration with Gradle)
dependencies {
  ...
  compile("org.springframework.boot:spring-boot-starter-data-rest")
  ...
}
在Maven配置Spring Boot(Spring Boot configuration with Maven)
<dependencies>
  ...
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
  </dependency>
  ...
</dependencies>
You don’t have to supply the version number if you are using the Spring Boot Gradle plugin or the Spring Boot Maven plugin.
如果你正在使用 Spring Boot Gradle plugin 或者 Spring Boot Maven plugin的话就不必提供版本号。

When using Spring Boot, Spring Data REST gets configured automatically.

当我们使用Spring Boot,Spring Data REST会自动配置。

添加 Spring Data REST 到 Gradle project(Adding Spring Data REST to a Gradle project)

To add Spring Data REST to a Gradle-based project, add the spring-data-rest-webmvc artifact to your compile-time dependencies:

基于Gradle项目添加Spring Data REST,添加spring-data-rest-webmvc生成你的编译时依赖项:

dependencies {
  … other project dependencies
  compile("org.springframework.data:spring-data-rest-webmvc:{version}")
}

添加Spring Data REST到Maven project(Adding Spring Data REST to a Maven project)

To add Spring Data REST to a Maven-based project, add the spring-data-rest-webmvc artifact to your compile-time dependencies:

基于Maven项目添加Spring Data REST,添加spring-data-rest-webmvc生成你的编译时依赖项:

<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-rest-webmvc</artifactId>
  <version>{version}</version>
</dependency>

配置Spring Data REST(Configuring Spring Data REST)

To install Spring Data REST alongside your existing Spring MVC application, you need to include the appropriate MVC configuration. Spring Data REST configuration is defined in a class called RepositoryRestMvcConfiguration and that class can just be imported into your applications configuration.

要在你现有的Spring MVC应用程序中安装Spring Data REST,你需要有适当的MVC结构。Spring Data REST配置定义在一个名叫RepositoryRestMvcConfiguration的类中并且这个类只可以导入你的应用程序配置。

This step is unnecessary if you are using Spring Boot’s auto-configuration. Spring Boot will automatically enable Spring Data REST when you include spring-boot-starter-data-rest and either in your list of dependencies, and you your app is flagged with either @SpringBootApplication or @EnableAutoConfiguration.
如果你是使用Spring Data REST的自动配置的话这一步是没有必要的。 Spring Boot将自动启用Spring Data REST当你包括spring-boot-starter-data-rest或者在你的依赖列表中, 你的应用程序被标记为 @SpringBootApplication@EnableAutoConfiguration.

To customize the configuration, register a RepositoryRestConfigurer (or extend RepositoryRestConfigurerAdapter) and implement or override the configure…-methods relevant to your use case.

自定义配置,创建一个RepositoryRestConfigurer (或者继承 RepositoryRestConfigurerAdapter) 然后实现或者重写configure…与你的用例有关的方法。

Make sure you also configure Spring Data repositories for the store you use. For details on that, please consult the reference documentation for the corresponding Spring Data module.

确定你还在为你使用的存储配置Spring Data库,对于细节,请查阅参考文献[corresponding Spring Data module](http://projects.spring.io/spring-data/)。

Spring Data REST的基本设置(Basic settings for Spring Data REST)

哪些库是默认存在的?(Which repositories get exposed by defaults?)

Spring Data REST uses a RepositoryDetectionStrategy to determine if a repository will be exported as REST resource or not. The following strategies (enumeration values of RepositoryDiscoveryStrategies) are available:

Spring Data REST使用RepositoryDetectionStrategy去确定是否要导出存储库作为剩余资源。以下策略(对RepositoryDiscoveryStrategies枚举值)是可用的:

Table 1. Repository detection strategies
Name Description

DEFAULT

Exposes all public repository interfaces but considers @(Repository)RestResource’s `exported flag.

ALL

Exposes all repositories independently of type visibility and annotations.

ANNOTATION

Only repositories annotated with @(Repository)RestResource are exposed, unless their exported flag is set to false.

VISIBILITY

Only public repositories annotated are exposed.

Table 2. 库检测策略
名称 描述

DEFAULT

公布所有的公共库的接口但是将@(Repository)RestResource’s 是exported的标志。

ALL

独立公开类型可见和注释的所有存储库。

ANNOTATION

只有标注了 @(Repository)RestResource的库才公开 ,除非它们exported的标志设置为false

VISIBILITY

只有公共库的注释会被公开。

改变基础的URI(Changing the base URI)

By default, Spring Data REST serves up REST resources at the root URI, "/". There are multiple ways to change the base path.

默认情况下,Spring Data REST提供了REST根资源URI, "/"。有多种方法去改变基础的路径。

With Spring Boot 1.2+, all it takes is a single property in application.properties:

在Spring Boot 1.2+,所有的它需要的是一个单一的属性application.properties:

spring.data.rest.basePath=/api

With Spring Boot 1.1 or earlier, or if you are not using Spring Boot, simply do this:

在Spring Boot 1.1或者更早的版本,或者你不使用Spring Boot,简单的来做这个:

@Configuration
class CustomRestMvcConfiguration {

  @Bean
  public RepositoryRestConfigurer repositoryRestConfigurer() {

    return new RepositoryRestConfigurerAdapter() {

      @Override
      public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        configuration.setBasePath("/api")
      }
    };
  }
}

Alternatively just register a custom implementation of RepositoryRestConfigurer as Spring bean and make sure it gets picked up by component scanning:

或者只是注册一个自定义实现的RepositoryRestConfigurer作为Spring bean并确保它通过了组件的扫描:

@Component
public class CustomizedRestMvcConfiguration extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    configuration.setBasePath("/api")
  }
}

Both of these approaches will change the base path to /api.

这两种方法都是将基本路径改为/api

更改其他的Spring Data REST属性(Changing other Spring Data REST properties)

There are many properties you can alter:

有许多属性你可以更改:

Table 3. Spring Boot configurable properties
Name Description

basePath

root URI for Spring Data REST

defaultPageSize

change default number of items served in a single page

maxPageSize

change maximum number of items in a single page

pageParamName

change name of the query parameter for selecting pages

limitParamName

change name of the query parameter for number of items to show in a page

sortParamName

change name of the query parameter for sorting

defaultMediaType

change default media type to use when none is specified

returnBodyOnCreate

change if a body should be returned on creating a new entity

returnBodyOnupdate

change if a body should be returned on updating an entity

Table 4. Spring Boot可配置的属性
名称 描述

basePath

Spring Data REST的根URI

defaultPageSize

更改单个页面中的项目的默认数量

maxPageSize

更改单个页面中的项目的最大数量

pageParamName

用于更改选择页的查询的参数的名称

limitParamName

更改页面中显示项目数的查询参数的名称

sortParamName

用于更改排序的查询的参数的名称

defaultMediaType

更改指定的默认媒体类型时使用

returnBodyOnCreate

如果创建一个新的实体应该返回它的主体进行更改

returnBodyOnupdate

如果更新一个实体应该应该返回它的主体进行更改

启动应用程序(Starting the application)

At this point, you must also configure your key data store.

在这一点上,你还必须配置你的关键数据的存储。

Spring Data REST officially supports:

Spring Data REST官方支持:

Here are some Getting Started guides to help you get up and running quickly:

下面是一些入门指南,以帮助您快速启动和运行:

These linked guides introduce how to add dependencies for the related data store, configure domain objects, and define repositories.

这些链接指南介绍如何为相关的数据存储区添加依赖关系,配置域对象,并定义存储库。

You can run your application as either a Spring Boot app (with links showns above) or configure it as a classic Spring MVC app.

你可以运行你的应用程序无论是作为一个Spring Boot应用程序(链接显示以上)或配置它作为经典的Spring MVC应用程序。

In general Spring Data REST doesn’t add functionality to a given data store. This means that by definition, it should work with any Spring Data project that supports the Repository programming model. The data stores listed above are simply the ones we have written integration tests to verify.
一般Spring Data REST并不给数据存储添加功能。这就意味着根据定义,它应该支持库编程模型与任何Spring Date项目进行工作。上面列出的简单的数据存储只是我们编写集成测试来验证的。

From this point, you can are free to customize Spring Data REST with various options.

资源库资源(Repository resources)

基本面(Fundamentals)

The core functionality of Spring Data REST is to export resources for Spring Data repositories. Thus, the core artifact to look at and potentially tweak to customize the way the exporting works is the repository interface. Assume the following repository interface:

Spring Data REST的基本功能就是给Spring Data资料库提供参考,所以,存在潜在调整的定制参考知识库的方式是库接口,假设有如下的库接口:

public interface OrderRepository extends CrudRepository<Order, Long> { }

For this repository, Spring Data REST exposes a collection resource at /orders. The path is derived from the uncapitalized, pluralized, simple class name of the domain class being managed. It also exposes an item resource for each of the items managed by the repository under the URI template /orders/{id}.

对于这个库,Spring Data REST在/orders给出了一个集合,路径是从小写形式,复数,简单的类域类的名称派生被管理路径,这也暴露了一个项目的资源为每个URI模板下/orders/{id}的信息库管理的项目。

By default the HTTP methods to interact with these resources map to the according methods of CrudRepository. Read more on that in the sections on collection resources and item resources.

默认情况下,HTTP方法与这些资源图接触的的方法都是来自CrudRepository的方法。 了解更多关于在[collection resources](http://docs.spring.io/spring-data/rest/docs/2.5.2.RELEASE/reference/html/#repository-resources.collection-resource) and [item resources](http://docs.spring.io/spring-data/rest/docs/2.5.2.RELEASE/reference/html/#repository-resources.item-resource).

默认状态码(Default status codes)

For the resources exposed, we use a set of default status codes:

在这个资源中,我们用一组默认的状态码:

  • 200 OK - for plain GET requests.

  • 201 Created - for POST and PUT requests that create new resources.

  • 204 No Content - for PUT, PATCH, and DELETE requests if the configuration is set to not return response bodies for resource updates (RepositoryRestConfiguration.returnBodyOnUpdate). If the configuration value is set to include responses for PUT, 200 OK will be returned for updates, 201 Created will be returned for resource created through PUT.

  • 200 OK - 用于普通的get请求。

  • 201 Created - 用于POSTPUT请求来创建新资源。

  • 204 No Content - 用于PUTPATCHDELETE请求,如果组态对于资源更新没有设置返回体,如果组态值设置包括相应PUT`200OK,将会返回更新, 201 Created 将会返回给资源通过PUT创建。

If the configuration values (RepositoryRestConfiguration.returnBodyOnUpdate and RepositoryRestConfiguration.returnBodyCreate) are explicitly set to null, the presence of the HTTP Accept header will be used to determine the response code.

如果配置值(RepositoryRestConfiguration.returnBodyOnUpdateRepositoryRestConfiguration.returnBodyCreate)显示设置为null,HTTP Accept标头的存在将被用来确定响应代码

资源的可发现性(Resource discoverability)

A core principle of HATEOAS is that resources should be discoverable through the publication of links that point to the available resources. There are a few competing de-facto standards of how to represent links in JSON. By default, Spring Data REST uses HAL to render responses. HAL defines links to be contained in a property of the returned document.

一个核心原则 [HATEOAS](https://spring.io/understanding/HATEOAS) 资源应该发现通过出版物的链接,指向可用资源。有几个相互竞争的实际标准如何表示链接的JSON。默认情况下,Spring Data REST [HAL](http://tools.ietf.org/html/draft-kelly-json-hal) 呈现相应。HAL定义链接中包含属性返回的列表。

Resource discovery starts at the top level of the application. By issuing a request to the root URL under which the Spring Data REST application is deployed, the client can extract a set of links from the returned JSON object that represent the next level of resources that are available to the client.

资源发现开始于应用程序的顶层。通过发出到在其下Spring Data REST应用部署在根URL的请求时,客户端可以提取一组从JSON返回的对象,它表示提供给客户端的资源的下一级的链接。

For example, to discover what resources are available at the root of the application, issue an HTTP GET to the root URL:

例如,要发现哪些资源可在应用程序的根目录下,发出HTTP`GET`到根网址:

curl -v http://localhost:8080/

< HTTP/1.1 200 OK
< Content-Type: application/hal+json

{ "_links" : {
    "orders" : {
      "href" : "http://localhost:8080/orders"
    },
    "profile" : {
      "href" : "http://localhost:8080/api/alps"
    }
  }
}

The property of the result document is an object in itself consisting of keys representing the relation type with nested link objects as specified in HAL.

结果文档的属性本身就是一个对象包括代表在HAL指定嵌套链接对象的关系型按键。

For more details about the profile link, see Application-Level Profile Semantics (ALPS).
有关profile配置文件链接的详细信息,请参阅[Application-Level Profile Semantics (ALPS)](http://docs.spring.io/spring-data/rest/docs/2.5.2.RELEASE/reference/html/#metadata.alps)。

资源集合(The collection resource)

Spring Data REST exposes a collection resource named after the uncapitalized, pluralized version of the domain class the exported repository is handling. Both the name of the resource and the path can be customized using the @RepositoryRestResource on the repository interface.

Spring Data REST公开领域类导出存储库处理的小写形式,复数版本命名的资源集合。两个资源和路径的名称可以用@ RepositoryRestResource在储存库接口上进行定制。

支持的HTTP方法(Supported HTTP Methods)

Collections resources support both GET and POST. All other HTTP methods will cause a 405 Method Not Allowed.

资源集合支持GETPOST。所有其他的HTTP方法会导致405方法不Allowed

GET

Returns all entities the repository servers through its findAll(…) method. If the repository is a paging repository we include the pagination links if necessary and additional page metadata.

返回所有通过它的实体findAll(…)方法实体库服务器。如果仓库是寻呼信息库,我们包括在必要的和额外的页面的元数据分页链接。

参数(Parameters)

If the repository has pagination capabilities the resource takes the following parameters:

如果存储库具有分页功能的资源采用下列参数:

  • page - the page number to access (0 indexed, defaults to 0).

  • size - the page size requested (defaults to 20).

  • sort - a collection of sort directives in the format ($propertyname,)+[asc|desc]?.

  • page - 页码访问(索引为0,默认为0)。

  • size - 请求的页面大小(默认为20)。

  • sort - 在格式短指令的集合 ($propertyname,)+[asc|desc]?.

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the findAll(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed - 如果没有出口的findAll(…) 方法 (通过 @RestResource(exported = false)) 或不存在存储库中.

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

HEAD

Returns whether the collection resource is available.

返回集合资源是否可用。

POST

Creates a new entity from the given request body.

创建从给定的请求主体的新实体。

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the save(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed -save(…)方法没有导出(通过@RestResource(出口= FALSE))或不存在存储库中的。

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

项目资源(The item resource)

Spring Data REST exposes a resource for individual collection items as sub-resources of the collection resource.

Supported HTTP methods

Item resources generally support GET, PUT, PATCH and DELETE unless explicit configuration prevents that (see below for details).

项目资源一般支持 GET,PUT,PATCHDELETE除非明确的配置阻止了(详见下文)。

GET

Returns a single entity.

返回单个实体。

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the findOne(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed - findOne(…)方法没有导出(通过@RestResource(出口= FALSE))或不存在存储库中的。

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

For every association of the domain type we expose links named after the association property. This can be customized by using @RestResource on the property. The related resources are of type association resource.

对于域类型的每个协会,我们揭露关联属性命名的连接。这可以通过使用上属性@ RestResource定制。相关的资源型[association resource]association resource

HEAD

Returns whether the item resource is available.

替换用附带的请求主体目标资源的状态。

PUT

Replaces the state of the target resource with the supplied request body.

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the save(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed - save(…) 方法没有导出(通过@RestResource(出口= FALSE))或不存在存储库中的。

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

补丁(PATCH)

Similar to PUT but partially updating the resources state.

类似PUT但部分更新资源的状态。

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the save(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed - save(…) 方法没有导出(通过@RestResource(出口= FALSE))或不存在存储库中的。

支持的媒体类型(Supported media types)
删除(DELETE)

Deletes the resource exposed.

删除暴露的资源。

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the delete(…) methods was not exported (through @RestResource(exported = false)) or is not present in the repository at all.

  • 405 Method Not Allowed - delete(…) 方法没有导出(通过@RestResource(出口= FALSE))或不存在存储库中的。

协议的资源(The association resource)

Spring Data REST exposes sub-resources of every item resource for each of the associations the item resource has. The name and path of the of the resource defaults to the name of the association property and can be customized using @RestResource on the association property.

Spring Data REST公开每个有关联的项目的每一项资源的子资源。这个名字和关联属性的名称的资源的默认路径,可以使用@ RestResource的关联属性进行定制。

支持的HTTP方法(Supported HTTP methods)

GET

Returns the state of the association resource

返回关联资源的状态

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

PUT

Binds the resource pointed to by the given URI(s) to the resource. This

结合所述资源所指向给定的URI(多个)到资源。

自定义状态码(Custom status codes)
  • 400 Bad Request - if multiple URIs were given for a to-one-association.

  • 400 Bad Request - 给予一个一对一关联多个URI。

支持的媒体类型(Supported media types)
  • text/uri-list - URIs pointing to the resource to bind to the association.

  • text/uri-list - 指向资源的URI绑定到的关联。

POST

Only supported for collection associations. Adds a new element to the collection.

仅支持收藏协会。添加到集合中的新元素。

支持的媒体类型(Supported media types)
  • text/uri-list - URIs pointing to the resource to add to the association.

  • text/uri-list - 指向资源的URI绑定到的关联。

DELETE

Unbinds the association.

解除绑定的关联。

自定义状态码(Custom status codes)
  • 405 Method Not Allowed - if the association is non-optional.

  • 405 Method Not Allowed - 该协会非可选。

搜索资源(The search resource)

The search resource returns links for all query methods exposed by a repository. The path and name of the query method resources can be modified using @RestResource on the method declaration.

搜索资源返回由存储库公开的所有查询方法链接。查询方法资源的路径和名称可以使用在方法声明@ RestResource进行修改。

支持的HTTP方法(Supported HTTP methods)

As the search resource is a read-only resource it supports GET only.

作为检索的搜索资源是一个只读资源仅支持GET

GET

Returns a list of links pointing to the individual query method resources

返回指向单个查询方法资源的链接列表

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

For every query method declared in the repository we expose a query method resource. If the resource supports pagination, the URI pointing to it will be a URI template containing the pagination parameters.

对于存储库中我们揭露的每一个申报查询方法query method resource. 如果资源支持分页,指向的URL将包含分页参数的URI模板。

HEAD

Returns whether the search resource is available. A 404 return code indicates no query method resources available at all.

返回搜索资源是否可用。404返回码表示根本没有查询方法可用资源。

查询方法资源(The query method resource)

The query method resource executes the query exposed through an individual query method on the repository interface.

查询资源方法执行查询是通过资源库接口上的单个查询方法。

支持的HTTP方法(Supported HTTP methods)

As the search resource is a read-only resource it supports GET only.

作为检索的资源是一个只读资源支持仅GET

GET

Returns the result of the query execution.

返回查询执行的结果。

参数(Parameters)

If the query method has pagination capabilities (indicated in the URI template pointing to the resource) the resource takes the following parameters:

如果查询方法具有分页功能(表明指向URI模板只想资源)则资源将采用下列参数:

  • page - the page number to access (0 indexed, defaults to 0).

  • size - the page size requested (defaults to 20).

  • sort - a collection of sort directives in the format ($propertyname,)+[asc|desc]?.

  • page - 页码访问(索引为0,默认为0)。

  • size - 请求的页面大小(默认为20)。

  • sort - 在这个版本中分类指令的集合($propertyname,)+[asc|desc]?.

支持的媒体类型(Supported media types)
  • application/hal+json

  • application/json

HEAD

Returns whether a query method resource is available.

返回查询方法资源是否可用。

分页和排序(Paging and Sorting)

This documents Spring Data REST’s usage of the Spring Data Repository paging and sorting abstractions. To familiarize yourself with those features, please see the Spring Data documentation for the Repository implementation you’re using.

This文件Spring Data REST中的Spring REST数据的使用和排序抽象。要熟悉使用这些功能,请参阅你用来实现的Spring Data文档

分页(Paging)

Rather than return everything from a large result set, Spring Data REST recognizes some URL parameters that will influence the page size and starting page number.

而不是从一个大的结果集返回所有东西,Spring Data REST承认某些URL参数会影响页面大小和起始页码。

If you extend PagingAndSortingRepository<T, ID> and access the list of all entities, you’ll get links to the first 20 entities. To set the page size to any other number, add a size parameter:

如果扩展PagingAndSortingRepository<T,ID>和访问所有实体的名单,你会得到链接到前20个实体。要设置页面大小,任何其他数字,添加一个size参数:

http://localhost:8080/people/?size=5

This will set the page size to 5.

这段代码将设置页面大小为五页。

To use paging in your own query methods, you need to change the method signature to accept an additional Pageable parameter and return a Page rather than a List. For example, the following query method will be exported to /people/search/nameStartsWith and will support paging:

如果要在自己的查询方式使用分页,您需要更改方法签名去接受一个额外的Pageable参数,并返回一个Page而非List。例如,下面的查询方法将出口到/people/search/nameStartsWith,将支持分页:

@RestResource(path = "nameStartsWith", rel = "nameStartsWith")
public Page findByNameStartsWith(@Param("name") String name, Pageable p);

The Spring Data REST exporter will recognize the returned Page and give you the results in the body of the response, just as it would with a non-paged response, but additional links will be added to the resource to represent the previous and next pages of data.

Spring Data REST exporter将在识别返回响应的结果Body中的Page,就像它响应非分页,但其他链接将被添加到资源来表示上一页和下一页数据的页。

Each paged response will return links to the previous and next pages of results based on the current page using the IANA defined link relations prev and next. If you are currently at the first page of results, however, no prev link will be rendered. The same is true for the last page of results: no next link will be rendered.

每个页面响应将返回链接到基于使用IANA定义的链接关系[prev]当前页面(http://www.w3.org/TR/html5/links.html#link成果的上一页和下一页型 - 上一个)和[next](http://www.w3.org/TR/html5/links.html#link-type-next)。 如果你目前正处于结果的第一页,但是,没有prev链接将被渲染。同样是结果的最后一页真:没有'next`链接将被渲染。

Look at the following example, where we set the page size to 5:

请看下面的例子中,我们将页面大小设置为5:

curl localhost:8080/people?size=5
{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons{&sort,page,size}", (1)
      "templated" : true
    },
    "next" : {
      "href" : "http://localhost:8080/persons?page=1&size=5{&sort}", (2)
      "templated" : true
    }
  },
  "_embedded" : {
  	... data ...
  },
  "page" : { (3)
    "size" : 5,
    "totalElements" : 50,
    "totalPages" : 10,
    "number" : 0
  }
}

At the top, we see _links:

在顶部,我们可以看到_links

1 This self link serves up the whole collection with some options
2 This next link points to the next page, assuming the same page size.
3 At the bottom is extra data about the page settings, including the size of a page, total elements, total pages, and the page number you are currently viewing.
4 这个self链接提供了整个收集与一些选项。
5 next链接指向下一个页面,假设在同一页面大小。
6 在底部是关于页面设置额外的数据,包括页面的大小,总的元素,总页数,目前正在查看的页面数。
When using tools like curl on the command line, if you have a "&" in your statement, wrap the whole URI with quotes.
当使用工具,如curl卷曲在命令行,如果你有一个引号“&”在声明中,包住整个URL。

It’s also important to notice that the self and next URIs are, in fact, URI templates. They accept not only size, but also page, sort as optional flags.

同样重要的是要注意到selfnext的URI,事实上是URI模板。他们接受不只是size,而且pagesort可选标志。

As mentioned, at the bottom of the HAL document, is a collection of details about the page. This extra information makes it very easy for you to configure UI tools like sliders or indicators to reflect overall position the user is in viewing the data. For example, the document above shows we are looking at the first page (with page numbers indexed to 0 being the first).

如所提到的,在HAL文档的底部,是关于页面细节的集合。这种额外的信息使得它很容易为你配置UI工具,比如滑块或指标来反映整体状况的用户在查看数据。例如,上面的文件表明,我们正在寻找在第一页(有页码索引到0是第一个)。

What happens if we follow the next link?

如果我们访问'next`链接会发生什么?

$ curl "http://localhost:8080/persons?page=1&size=5"
{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons{&sort,projection,page,size}",
      "templated" : true
    },
    "next" : {
      "href" : "http://localhost:8080/persons?page=2&size=5{&sort,projection}", (1)
      "templated" : true
    },
    "prev" : {
      "href" : "http://localhost:8080/persons?page=0&size=5{&sort,projection}", (2)
      "templated" : true
    }
  },
  "_embedded" : {
	... data ...
  },
  "page" : {
    "size" : 5,
    "totalElements" : 50,
    "totalPages" : 10,
    "number" : 1 (3)
  }
}

This looks very similar, except for the following differences:

这看起来非常相似,除了以下差异:

1 The next link now points to yet another page, indicating it’s relative perspective to the self link.
2 A prev link now appears, giving us a path to the previous page.
3 The current number is now 1 (indicating the second page).
4 现在的“next”链接指向另一个页面,表明它的相对角度对 self的链接。
5 现在似乎prev链接,给我们一个路径前一页。
6 目前的数量是1(显示第二页)。

This feature makes it quite easy to map optional buttons on the screen to these hypermedia controls, hence allowing easy navigational features for the UI experience without having to hard code the URIs. In fact, the user can be empowered to pick from a list of page sizes, dynamically changing the content served, without having to rewrite the next and `prev controls at the top or bottom.

这一特性使它很容易可选的按钮在屏幕上映射到这些超媒体控制,因此可以很容易地使导航功能的UI体验不用硬编URI。事实上,可以授权用户从列表中选择页面大小,动态更改内容服务,而无需重写nextprev控制顶部或底部。

排序(Sorting)

Spring Data REST recognizes sorting parameters that will use the Repository sorting support.

Spring Data REST参数排序使用存储库分类的支持。

To have your results sorted on a particular property, add a sort URL parameter with the name of the property you want to sort the results on. You can control the direction of the sort by appending a , to the the property name plus either asc or desc. The following would use the findByNameStartsWith query method defined on the PersonRepository for all Person entities with names starting with the letter "K" and add sort data that orders the results on the name property in descending order:

结果排序在一个特定的属性,添加一个sort`URL参数和属性的名称你想进行排序的结果中。你可以控制的方向通过添加一个,属性名称`ascdesc。下面将使用findByNameStartsWith查询方法定义在所有 PersonPersonRepository实体以字母"K"开头的名称并添加订单数据,结果在降序排列的name属性:

curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"

To sort the results by more than one property, keep adding as many sort=PROPERTY parameters as you need. They will be added to the Pageable in the order they appear in the query string.

排序结果由多个属性,不断添加尽可能多的sort=PROPERTY的参数,它们将被按照出现在查询字符串中的顺序添加到Pageable中。

域对象交涉(Domain Object Representations)

对象映射(Object Mapping)

Spring Data REST returns a representation of a domain object that corresponds to the requested Accept type specified in the HTTP request.

Spring Data REST返回对应于请求的HTTP请求中指定Accept类型的域对象的表示。

Currently, only JSON representations are supported. Other representation types can be supported in the future by adding an appropriate converter and updating the controller methods with the appropriate content-type.

目前,只有JSON支持。其他表示类型可以在将来通过添加适当的转换器,并更新与适当的内容类型的控制器方法的支持。

Sometimes the behavior of the Spring Data REST’s ObjectMapper, which has been specially configured to use intelligent serializers that can turn domain objects into links and back again, may not handle your domain model correctly. There are so many ways one can structure your data that you may find your own domain model isn’t being translated to JSON correctly. It’s also sometimes not practical in these cases to try and support a complex domain model in a generic way. Sometimes, depending on the complexity, it’s not even possible to offer a generic solution.

有时候,Spring Data REST的对象映射,已专门配置为使用智能串行器,可以把域对象为链接,然后再返回,可能无法正确处理您的域模型的行为。有很多方法可以组织你的数据, 你会发现你自己的域模型没有被正确翻译成JSON。这也是有时在这些情况下,实际的尝试,并支持复杂的域模型的通用方法。有时,根据不同的复杂性,这可能提供一个通用的解决方案。

添加自定义的串行器给Jackson的对象映射(Adding custom (de)serializers to Jackson’s ObjectMapper)

To accommodate the largest percentage of use cases, Spring Data REST tries very hard to render your object graph correctly. It will try and serialize unmanaged beans as normal POJOs and it will try and create links to managed beans where that’s necessary. But if your domain model doesn’t easily lend itself to reading or writing plain JSON, you may want to configure Jackson’s ObjectMapper with your own custom type mappings and (de)serializers.

为了适应用例的比例最大化,Spring Data REST很努力的试图正确地呈现你的对象图。它会尝试和序列化非托管正常的POJO,它会尝试创建链接到托管的bean,这是很有必要的。 但是,如果你的领域模型不易读或写成纯JSON,你可能需要配置Jackson的ObjectMapper与自己的自定义类型映射和(反)序列化。

抽象类注册(Abstract class registration)

One key configuration point you might need to hook into is when you’re using an abstract class (or an interface) in your domain model. Jackson won’t know by default what implementation to create for an interface. Take the following example:

当在领域模型使用抽象类(或接口),一个可能需要挂接到关键的配置点。Jackson默认将不知道什么实现创建一个接口。看看下面的例子:

@Entity
public class MyEntity {
  @OneToMany
  private List<MyInterface> interfaces;
}

In a default configuration, Jackson has no idea what class to instantiate when POSTing new data to the exporter. This is something you’ll need to tell Jackson either through an annotation, or, more cleanly, by registering a type mapping using a Module.

在默认配置中,Jackson当实例化哪个类,已经不知道什么时候再发布新的数据给出口商。这是你需要告诉Jackson要么通过注解,或者更干净,通过注册使用Module一个类型映射。

To add your own Jackson configuration to the ObjectMapper used by Spring Data REST, override the configureJacksonObjectMapper method. That method will be passed an ObjectMapper instance that has a special module to handle serializing and deserializing `PersistentEntity`s. You can register your own modules as well, like in the following example.

要添加自己的Jackson配置由Spring数据REST使用ObjectMapper,覆盖configureJacksonObjectMapper方法。该方法将传递具有特殊的模块来处理序列化和反序列化PersistentEntity`s一个`ObjectMapper实例。你也可以注册自己的模块,就像下面的例子。

@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
    objectMapper.registerModule(new SimpleModule("MyCustomModule") {
        @Override
        public void setupModule(SetupContext context) {
            context.addAbstractTypeResolver(
                new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
                                                            MyInterfaceImpl.class)
            );
        }
    });
}

Once you have access to the SetupContext object in your Module, you can do all sorts of cool things to configure Jackson’s JSON mapping. You can read more about how Modules work on Jackson’s wiki: http://wiki.fasterxml.com/JacksonFeatureModules

一旦你在Module中有机会获得在SetupContext对象,你可以做各种很酷的事情来配置Jackson的JSON映射。你可以阅读更多有关`Module`s对杰克逊的维基是如何工作的:http://wiki.fasterxml.com/JacksonFeatureModules[ http://wiki.fasterxml.com/JacksonFeatureModules ]

添加自定义序列化的域类型(Adding custom serializers for domain types)

If you want to (de)serialize a domain type in a special way, you can register your own implementations with Jackson’s ObjectMapper and the Spring Data REST exporter will transparently handle those domain objects correctly. To add serializers, from your setupModule method implementation, do something like the following:

如果你想用一个特殊的方式(反)序列化域名类型,你可以注册Jackson自己的实现ObjectMapper和Spring Data REST出口将透明地正确地处理这些域对象。要添加序列化,从你的setupModule方法实现,像以下几种做法:

@Override
public void setupModule(SetupContext context) {
  SimpleSerializers serializers = new SimpleSerializers();
  SimpleDeserializers deserializers = new SimpleDeserializers();

  serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
  deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());

  context.addSerializers(serializers);
  context.addDeserializers(deserializers);
}

预测和摘要(Projections and Excerpts)

Spring Data REST presents a default view of the domain model you are exporting. But sometimes, you may need to alter the view of that model for various reasons. In this section, you will learn how to define projections and excerpts to serve up simplified and reduced views of resources.

Spring Data REST提出了一个您正在导出的域模型的默认视图,但是有时候,你需要因为各种各样的理由来更改这些模型的意见。在这个部分,你将会学习到如何 明确预测以及更加简单提供摘要以及减少对资源的一些意见。

Projections

Look at the following domain model:

看下面的域模型:

@Entity
public class Person {

  @Id @GeneratedValue
  private Long id;
  private String firstName, lastName;

  @OneToOne
  private Address address;
  …
}

This Person has several attributes:

这个`Perso`n有以下这些属性:

  • id is the primary key

  • firstName and lastName are data attributes

  • address is a link to another domain object

  • id是主键

  • firstNamelastName是数据属性

  • address是一个链接到另一个域的对象

Now assume we create a corresponding repository as follows:

现在假设我们创建了一个对应的存储,如下:

interface PersonRepository extends CrudRepository<Person, Long> {}

By default, Spring Data REST will export this domain object including all of its attributes. firstName and lastName will be exported as the plain data objects that they are. There are two options regarding the address attribute. One option is to also define a repository for Address objects like this:

在默认情况下,Spring Data REST 将会输出这个域对象包括里面所有的属性firstNamelastName 会被作为清楚的数据对象被输出。这里有两个选择关于这个address属性。一个选择也规定对于address对象的存储如下

interface AddressRepository extends CrudRepository<Address, Long> {}

In this situation, a Person resource will render the address attribute as a URI to it’s corresponding Address resource. If we were to look up "Frodo" in the system, we could expect to see a HAL document like this:

在这种情况下,Person的资源将会作为一个URI给予Address属性来对应他的Address资源,如果我们在这个系统里面要查找“Fordo”,我们可以希望看到的HAL文档如下

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}

There is another route. If the Address domain object does not have it’s own repository definition, Spring Data REST will inline the data fields right inside the Person resource.

这里有另一条路线,如果这个address域对象没有他本身的存储定义,Spring Data REST将会对内部的person资源内联数据字段。

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "address" : {
    "street": "Bag End",
    "state": "The Shire",
    "country": "Middle Earth"
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    }
  }
}

But what if you don’t want address details at all? Again, by default, Spring Data REST will export all its attributes (except the id). You can offer the consumer of your REST service an alternative by defining one or more projections.

但是如果你不想要address的所有细节?,再一次,在默认情况下,Spring Data REST将会输出这个的所有属性(除id),你可以为消费者提供你的可替代的REST服务通过定义一个或者多个预测方法

@Projection(name = "noAddresses", types = { Person.class }) (1)
interface NoAddresses { (2)

  String getFirstName(); (3)

  String getLastName(); (4)
}

This projection has the following details:

这个规划有以下的细节:

1 The @Projection annotation flags this as a projection. The name attributes provides the name of the projection, which you’ll see how to use shortly. The types attributes targets this projection to only apply to Person objects.
2 It’s a Java interface making it declarative.
3 It exports the firstName.
4 It exports the lastName.
5 @Projection 注释标志是一个投影,name属性提供了投影名称,你将会见识到如何简单的利用。types属性目标这个投影只试用Person对象.
6 它是一个java接口的声明。
7 它输出firstname
8 它输出lastname

The NoAddresses projection only has getters for firstName and lastName meaning that it won’t serve up any address information. Assuming you have a separate repository for Address resources, the default view from Spring Data REST is slightly different as shown below:

NoAddress项目里面只有firsnamelastname的getter方法,意味着它不会提供任何地址信息。假设你有一个单独的存储库地址资源,spring Data REST的默认视图有点不同,如下

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1{?projection}", (1)
      "templated" : true (2)
    },
    "address" : {
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}
1 There is a new option listed for this resource, {?projection}.
2 The self URI is a URI Template.
3 对于新的资源这里有一个新的选择清单{?projection}
4 self URI是一个URI模板。

To view apply the projection to the resource, look up http://localhost:8080/persons/1?projection=noAddresses.

The value supplied to the projection query parameter is the same as specified in @Projection(name = "noAddress"). It has nothing to do with the name of the projection’s interface.
提供给投影查询参数的值在@Projection指定 @Projection(name = "noAddress").一样,这和投影的接口名称无关。

It’s possible to have multiple projections.

也可能可以有多个projections。

Visit Projections to see an example project you can experiment with.
您可以尝试访问预测看一个示例项目Projections

How does Spring Data REST finds projection definitions?

Spring Data REST如何找到projections的定义?

  • Any @Projection interface found in the same package as your entity definitions (or one of it’s sub-packages) is registered.

  • You can manually register via RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…).

  • 任何@Projection接口在同一个包中发现作为实体定义(或它的子包)是已登记的。

  • 您可以手动注册通过RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…)

In either situation, the interface with your projection MUST have the @Projection annotation.

在这两种情况下,接口与投影一定要用@Projection注释。

发现现有的投影(Finding existing projections)

Spring Data REST exposes Application-Level Profile Semantics (ALPS) documents, a micro metadata format. To view the ALPS metadata, follow the profile link exposed by the root resource. If you navigate down to the ALPS document for Person resources (which would be /alps/persons), you can find many details about Person resources. Projections will be listed along with the details about the GET REST transition, something like this:

Spring Data REST显示Application-Level Profile Semantics (ALPS)文件,一个微元数据格式。为了查看ALPS的元数据,按照配置文件profile 资源查找。如果你在Person资源下导航ALPS资源文档(这将是alps/persons),你将会发现一些person资源的细节。预测也会随着细节列出关于GET REST转换,如下

{ …
  "id" : "get-person", (1)
  "name" : "person",
  "type" : "SAFE",
  "rt" : "#person-representation",
  "descriptors" : [ {
    "name" : "projection", (2)
    "doc" : {
      "value" : "The projection that shall be applied when rendering the response. Acceptable values available in nested descriptors.",
      "format" : "TEXT"
    },
    "type" : "SEMANTIC",
    "descriptors" : [ {
      "name" : "noAddresses", (3)
      "type" : "SEMANTIC",
      "descriptors" : [ {
        "name" : "firstName", (4)
        "type" : "SEMANTIC"
      }, {
        "name" : "lastName", (4)
        "type" : "SEMANTIC"
      } ]
    } ]
  } ]
},
…
1 This part of the ALPS document shows details about GET and Person resources.
2 Further down are the projection options.
3 Further down you can see projection noAddresses listed.
4 The actual attributes served up by this projection include firstName and lastName.
5 alps这部分文档显示关于getperson资源的细节。
6 进一步降低Projection的选项。
7 进一步降低你可以看到的`noaddress`Projection清单。
8 这个Projection提供实际的属性包括firstNamelastName

Projection definitions will be picked up and made available for clients if they are:

Projection的定义会被采用并且为客户提供,如果他们是:

  • Flagged with the @Projection annotation and located in the same package (or sub-package) of the domain type, OR

  • Manually registered via RepositoryRestConfiguration.getProjectionConfiguration().addProjection(…).

引进隐藏数据(Bringing in hidden data)

So far, you have seen how projections can be used to reduce the information that is presented to the user. Projections can also bring in normally unseen data. For example, Spring Data REST will ignore fields or getters that are marked up with @JsonIgnore annotations. Look at the following domain object:

到目前为止,您已经看到了如何使用预测来减少信息呈现给用户。预测还可以引入通常看不见的数据。例如Spring Data REST将忽略数据字段或getter与@JsonIgnore标记注释,看看下面的域对象:

@Entity
public class User {

	@Id @GeneratedValue
	private Long id;
	private String name;

	@JsonIgnore private String password; (1)

	private String[] roles;
  …
1 Jackson’s @JsonIgnore is used to prevent the password field from getting serialized into JSON.
2 Jackson 的 @JsonIgnore 用于防止密码字段序列化为JSON。

This User class can be used to store user information as well as integration with Spring Security. If you create a UserRepository, the password field would normally have been exported. Not good! In this example, we prevent that from happening by applying Jackson’s @JsonIgnore on the password field.

这个user类可用于存储用户信息以及集成Spring Security。如果您创建了一个UserRepository,密码字段通常已经输出。不是很好! 在这个例子中,我们运用jackson 的 @JsonIgnore预防这样的事情发生在password

Jackson will also not serialize the field into JSON if @JsonIgnore is on the field’s corresponding getter function.
如果@JsonIgnore在领域对应getter函数那么jackson也没有序列化这个领域为json。

However, projections introduce the ability to still serve this field. It’s possible to create a projection like this:

然而,预测引入仍为这一领域的能力。可以创建这样的一个projections:

@Projection(name = "passwords", types = { User.class })
interface PasswordProjection {

  String getPassword();
}

If such a projection is created and used, it will side step the @JsonIgnore directive placed on User.password.

如果创建和使用这样一个投影,它将@JsonIgnore指令放在User.password.

This example may seem a bit contrived, but it’s possible with a richer domain model and many projections, to accidentally leak such details. Since Spring Data REST cannot discern the sensitivity of such data, it is up to the developers to avoid such situations.
这个例子似乎有点做作,但有可能与更丰富的领域模型和许多预测.,不小心泄漏这样的细节.因为 Spring Data REST不能辨别这些数据的敏感性,它由开发人员来避免这种情况。

Projections can also generate virtual data. Imagine you had the following entity definition:

Projections还可以生成虚拟数据。想象你有以下实体的定义:

@Entity
public class Person {

  ...
  private String firstName;
  private String lastName;

  ...
}

You can create a projection that combines these two data fields together like this:

您可以创建一个投影相结合这两个数据字段一起像这样

@Projection(name = "virtual", types = { Person.class })
public interface VirtualProjection {

  @Value("#{target.firstName} #{target.lastName}") (1)
  String getFullName();

}
1 Spring’s @Value annotation let’s you plugin a SpEL expression that takes the target object, and splices together its firstName and lastName attributes to render a read-only fullName.
2 Spring的@ value注释让你插入一个SpEL 表达式来获取目标对象,和拼接在一起的FirstNameLastName属性为只读FullName。

摘要(Excerpts)

An excerpt is a projection that is applied to a resource collection automatically. For an example, you can alter the PersonRepository as follows:

摘录是一个projection,应用于资源自动收集。例如,你可以改变personrepository,如下:

@RepositoryRestResource(excerptProjection = NoAddresses.class)
interface PersonRepository extends CrudRepository<Person, Long> {}

This directs Spring Data REST to use the NoAddresses projection when embedding Person resources into collections or related resources.

这指示Spring Data REST来用NoAddresses投影当Person的资源嵌入到集合或相关资源中。

Excerpt projections are NOT applied to single resources automatically. They have to be applied deliberately. Excerpt projections are meant to provide a default preview of collection data, but not when fetching individual resources. See Why is an excerpt projection not applied automatically for a Spring Data REST item resource? for a discussion on the subject.
摘录的预测并 不适用单一资源 自动,他们必须谨慎被使用,摘录的预测是为了提供一个默认的预览数据采集 但不是在获取个人资源。 为什么摘录投影不是Spring Data REST自动申请数据其他项资源?作为一个话题讨论.

In addition to altering the default rendering, excerpts have additional rendering options as shown below.

除了改变缺省呈现,摘录了额外的渲染选项如下所示

摘录经常访问数据(Excerpting commonly accessed data)

A common situation with REST services arises when you compose domain objects. For example, a Person is stored in one table and their related Address is stored in another. By default, Spring Data REST will serve up the person’s address as a URI the client must navigate. But if it’s common for consumers to always fetch this extra piece of data, an excerpt projection can go ahead and inline this extra piece of data, saving you an extra GET. To do so, let’s define another excerpt projection:

与REST服务出现常见的情况,当你组成域对象。例如,Person都存储在一个表及其相关address存储在另一个地方默认情况下Spring Data REST 将会提供人的address作为URI客户机必须导航。如果消费者总是拿到这块数据的额外一部分,摘录投影可以继续进行以及内联这个额外的数据模块。 储存你一个额外的GET。为此,我们定义一个摘录投影:

@Projection(name = "inlineAddress", types = { Person.class }) (1)
interface InlineAddress {

  String getFirstName();

  String getLastName();

  Address getAddress(); (2)
}
1 This projection has been named inlineAddress.
2 This projection adds in getAddress which returns the Address field. When used inside a projection, it causes the information to be inlined.
3 这个被命名为inlineaddress投影。
4 这个返回address的投影添加进getAddress.当使用这个投影,这使得信息被内联。

We can plug it into the PersonRepository definition as follows:

我们能按照如下插入PersonRepository定义:

@RepositoryRestResource(excerptProjection = InlineAddress.class)
interface PersonRepository extends CrudRepository<Person, Long> {}

This will cause the HAL document to appear as follows:

这将导致HAL文件出现如下:

{
  "firstName" : "Frodo",
  "lastName" : "Baggins",
  "address" : { (1)
    "street": "Bag End",
    "state": "The Shire",
    "country": "Middle Earth"
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons/1"
    },
    "address" : { (2)
      "href" : "http://localhost:8080/persons/1/address"
    }
  }
}

This should appear as a mix of what you’ve seen so far.

这应该会出现在你所看到的东西的组合中。

1 The address data is inlined directly, so you don’t have to navigate to get it.
2 The link to the Address resource is still provided, making it still possible to navigate to its own resource.
3 address数据是直接内联,所以你不必导航得到这个。
4 连接到Address资源依然被提供,使它仍然可以导航到自己的资源。
Configuring @RepositoryRestResource(excerptProjection=…​) for a repository alters the default behavior. This can potentially case breaking change to consumers of your service if you have already made a release. Use with caution.
配置@RepositoryRestResource(excerptProjection=…​)为了一个库改变默认行为。如果你已经做了一个发布,这个能破坏改变消费者对你的服务。小心使用。

在头文件下有条件的操作(Conditional Operations with Headers)

This section shows how Spring Data REST uses standard HTTP headers to enhance performance, conditionalize operations, and easily contribute to a more sophisticated frontend.

本节将展示 Spring Data REST 如何利用标准的HTTP来完成表现。条件化操作,很容易导致一个更复杂的前端。

ETag, If-Match, 和 If-None-Match 头文件(ETag, If-Match, and If-None-Match headers)

The ETag header provides a way to tag resources. This can prevent clients from overriding each other while also making it possible to reduce unnecessary calls.

ETag header提供了一个方法来附加资源。这可以防止客户端相互覆盖,同时也使有可能减少不必要的调用。

Example 3. 一个有版本号的POJO(A POJO with a version number)
public class Sample {

	@Version Long version; (1)

	Sample(Long version) {
		this.version = version;
	}
}
1 Spring Data Commons’s @Version annotation flags this field as a version marker.
2 Spring Data普通的 @Version注释标记这个领域作为一个版本标记。

This POJO, when served up as a REST resource by Spring Data REST, will have an ETag header with the value of the version field.

这个POJO,当通过 Spring Data RES被提供为一个REST,将会有一个版本字段的值的ETag header。

We can conditionally PUT, PATCH, or DELETE that resource if we supply a If-Match header like this:

我们能有条件的对数据进行PUT, PATCH, 或者 DELETE如果我们提供了一个像这个一样的 If-Match header

curl -v -X PATCH -H 'If-Match: <value of previous ETag>' ...

Only if the resource’s current ETag state matches this If-Match header will the operation be carried out. This prevents clients from stomping on each other. Two different clients can fetch the resource and have an identical ETag. If one client updates the resource, it will get a new ETag in the response. But the first client still has the old header. If that client attempts an update with the If-Match header, the update will fail because they no longer match. Instead, that client will receive an HTTP 412 Precondition Failed message to be sent back. The client can then catch up however is necessary.

只有当资源现在的ETag状态和If-Match header相匹配,这个动作才会被开展。这可以防止客户端操作和其他的操作重合。 不同的客户端可以获取资源,并有一个相同的ETag 。如果一个客户端更新资源,在回复里面将会得到一个新的ETag。 但是第一个客户依然有旧的头文件。如果一个客户端尝试更新If-Match header,这个更新将会失败因为他们不匹配。 相反,这个客户端将会收到一个被送回来的HTTP412 Precondition Failed信息。客户端可以赶上进度,尽管这是必须的。

The term "version" may carrry different semantics with different data stores, and even different semantics within your application. Spring Data REST effectively delegates to the data store’s metamodel to discern if a field is versioned, and if so, only allow the listed updates if ETags match.
“版本”可以用不同的语义,不同的数据存储区,甚至不同的语义,在您的应用程序。Spring Data REST有效地委托给数据存储的元模型辨别字段是否符合版本如果是,如果ETags相同,只允许列出的更新。

The If-None-Match header provides an alternative. Instead of conditional updates, If-None-Match allow conditional queries.

If-None-Match header提供了一种可以替代的方案而不是有条件的更新,If-None-Match允许条件查询。

curl -v -H 'If-None-Match: <value of previous etag>' ...

This command (by default) executes a GET. Spring Data REST will check for If-None-Match headers while doing a GET. If the header MATCHES the ETag, it will conclude nothing has changed, and instead of sending a copy of the resource, instead send back an HTTP 304 Not Modified status code. Semantically, it reads "If this supplied header value doesn’t match the server-side version, then send me the whole resource, otherwise, don’t send me anything."

这个命令(默认情况下)执行一个GET,当在执行GET,Spring Data REST将会检查 If-None-Match headers如果这个头文件和ETag匹配,他将会结束,没有东西改变。而不是发送一个副本资源,是寄回一个HTTP 304 Not Modified 状态代码,从语义上讲,它读作“如果这个提供的头文件不匹配的服务器端的版本,然后发送我的整个资源,否则,不要给我任何东西。

This POJO is from an ETag-based unit test, so it doesn’t have @Entity (JPA) or @Document (MongoDB) annotations as expected in application code. It simply focuses on how a field with @Version results in an ETag header.
这是一个基于POJO从它的单元测试,所以这个没有` @Entity (JPA)` 或者 @Document (MongoDB)注释如预期的应用程序代码。他只是集中在一个领域用 @Version在ETag的头文件。

If-Modified-Since头文件(If-Modified-Since header)

The If-Modified-Since header provides a way to check if a resource has been updated since the last request to avoid resending the same data.

If-Modified-Since header提供了一个方法来检查自从最后一个请求更新开始是否资源一直以来避免重新发送相同的数据。

Example 4. 域类型中捕获的最后一个修改日期(The last modification date captured in a domain type)
1 Spring Data Commons’s @LastModifiedDate annotation allows capturing this information in multiple formats (JodaTime’s DateTime, legacy Java Date and Calendar, JDK8 date/time types, as well as long/Long).
2 Spring Data Commons的` @LastModifiedDate`注释允许以多种形式捕获这些信息。(JodaTime’s DateTime, legacy Java Date and Calendar, JDK8 date/time types, 以及 long/Long)。

With this field, Spring Data REST will return a Last-Modified header like this:

在这个域下 Spring Data REST将会返回一个Last-Modified头文件如下:

Last-Modified: Wed, 24 Jun 2015 20:28:15 GMT

This value can be capture and used for subsequent queries to avoid fetching the same data twice if it hasn’t been updated.

此值可以被捕获,并用于后续的查询,如果它没有被更新,可以避免两次获取相同的数据。

curl -H "If-Modified-Since: Wed, 24 Jun 2015 20:28:15 GMT" ...

With this simple command, you are asking that a resource only be fetched if it’s changed since that time. If so, you will get a revised Last-Modified header to update the client. If not, you will receive an HTTP 304 Not Modified status code.

有了这个简单的命令,如果从那个时候被改变了你要求的资源只会被拿来。如果是这样的话,你会得到一个修正的 Last-Modified头文件来更新客户端,如果不是你将会收到一个 HTTP 304 Not Modified状态代码。

The header is perfectly formatted to send back for a future query.

header是完全格式化的,以发送回一个未来的查询。

Don’t mix and match header value with different queries. Results could be disastrous. ONLY use the header values when you are requesting the exact same URI and parameters.
不要混合和匹配不同查询的标题值。结果可能是灾难性的。只有当你请求相同的URI和参数,才使用头文件的值。

构建一个高效的前端(Architecting a more efficient frontend)

ETags combined with the If-Match and If-None-Match headers empower you to build frontend that is more friendly to consumer’s data plans and mobile battery lives.

ETags结合 If-MatchIf-None-Match 头文件授权你去建立前端,使得消费者的数据计划和手机电池的生活更友好。

  1. Identify the entities that need locking and add a version attribute. HTML5 nicely supports data-* attributes, so store it in the DOM somewhere like data-etag attribute.

  2. Identify the entiries that would benefit from tracking most recent updates. When fetching these resources, store the Last-Modified in the DOM (data-last-modified perhaps).

  3. When fetching resources, also embed self URIs into your DOM nodes (perhaps data-uri or data-self) so it’s very easy to go back to the resource.

  4. Adjust PUT/PATCH/DELETE operations to use If-Match and also handle HTTP 412 Precondition Failed status codes.

  5. Adjust GET operations to use If-None-Match, If-Modified-Since, and also handle HTTP 304 Not Modified status codes.

  6. 确定需要锁定的实体并添加一个版本属性。HTML5很好的支持-属性数据,所以把它存储在一个有点像data-etag 属性的DOM里。

  7. 确定一个路口将有利于从更新中获益。当获取这些资源,把它存储到DOM里面的Last-Modified(也许是data-last-modified

  8. 当获取资源,并且嵌入自我的URI到您的DOM节点(也许是data-uri或者data-self),所以也很容易返回资源

  9. 调整 PUT/PATCH/DELETE操作来用If-Match 而且也处理HTTP 412 Precondition Failed状态代码。

  10. 调整GET操作来用If-None-Match, If-Modified-Since,并处理 HTTP 304 Not Modified状态代码.

By embedding ETags and Last-Modified values into your DOM (or perhaps elsewhere for a native mobile app), you can then reduce the consumption of data/battery by NOT retrieving the same thing over and over. You can also avoid colliding with other clients, and instead, be alerted when you need to reconcile differences.

通过嵌入ETagsLast-Modified值进入你的DOM(对于本机移动app也可能是在其他地方)你可以减少消费的数据/电池通过没有一遍又一遍检索同样的事情。你也可以避免和其他客户的碰撞,相反,这是提醒你需要调节差异.

Hence, with just a little tweaking on your frontend and some entity-level edits, the backend will serve up time sensitive details you can cash in on when building a customer-friendly client.

因此,在你的前端和一些实体编辑上只要有一点小的调整,后台将提供一些你可以利用在构建对客户端的敏感的细节。

验证(Validation)

There are two ways to register a Validator instance in Spring Data REST: wire it by bean name or register the validator manually. For the majority of cases, the simple bean name prefix style will be sufficient.

在Spring Data REST这里有两个方法来注册一个Validator的实例:通过bean name连线这个或者手动验证注册。 在大多数情况下,简单的bean name前缀样式将会很充分。

In order to tell Spring Data REST you want a particular Validator assigned to a particular event, you simply prefix the bean name with the event you’re interested in. For example, to validate instances of the Person class before new ones are saved into the repository, you would declare an instance of a Validator<Person> in your ApplicationContext with the bean name "beforeCreatePersonValidator". Since the prefix "beforeCreate" matches a known Spring Data REST event, that validator will be wired to the correct event.

为了告诉 Spring Data REST你想要的一个特殊的Validator分配给一个特殊的事件,只需要将你感兴趣的事情放在bean name 之前。例如,为了验证实例Person类在新的已经保存的库之前,你将会声明一个Validator<Person>实例 在你的ApplicationContext用beanname“beforeCreatePersonValidator”,因为前缀“beforecreate”匹配一个已知的Spring Data REST 事件这个验证器将会连接到正确的事件。

手动分配验证器(Assigning Validators manually)

If you would rather not use the bean name prefix approach, then you simply need to register an instance of your validator with the bean whose job it is to invoke validators after the correct event. In your configuration that subclasses Spring Data REST’s RepositoryRestMvcConfiguration, override the configureValidatingRepositoryEventListener method and call the addValidator method on the ValidatingRepositoryEventListener, passing the event you want this validator to be triggered on, and an instance of the validator.

如果你不想使用bean name 前缀方法。你只需要用bean调用验证正确的事件后的工作登记您的验证实例。 在你的配置的之类Spring Data REST’s RepositoryRestMvcConfiguration,在ValidatingRepositoryEventListener重写configureValidatingRepositoryEventListener方法以及命令addValidator方法 通过事件你想要这个验证器来触发,和验证器实例。

@Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
  v.addValidator("beforeSave", new BeforeSaveValidator());
}

Events

There are eight different events that the REST exporter emits throughout the process of working with an entity. Those are:

这里有八种不同的事件,其中剩下的出口方发送遍及所有方面的实体工作的加工,这些都是:

  • BeforeCreateEvent

  • AfterCreateEvent

  • BeforeSaveEvent

  • AfterSaveEvent

  • BeforeLinkSaveEvent

  • AfterLinkSaveEvent

  • BeforeDeleteEvent

  • AfterDeleteEvent

Writing an ApplicationListener

There is an abstract class you can subclass which listens for these kinds of events and calls the appropriate method based on the event type. You just override the methods for the events you’re interested in.

有一个抽象类可以子类侦听这些事件,并根据事件类型调用相应的方法。你只是重写了你感兴趣的该事件的方法。当然,有一件事情你要注意的是,它是没有区别的,基于实体类型的,你只能自己来检查他。

public class BeforeSaveEventListener extends AbstractRepositoryEventListener {

  @Override
  public void onBeforeSave(Object entity) {
    ... logic to handle inspecting the entity before the Repository saves it
  }

  @Override
  public void onAfterDelete(Object entity) {
    ... send a message that this entity has been deleted
  }
}

One thing to note with this approach, however, is that it makes no distinction based on the type of the entity. You’ll have to inspect that yourself.

用这种方法有一点要注意,尽管它没有基于实体类型区分。你必须自己检查。

Writing an annotated handler

Another approach is to use an annotated handler, which does filter events based on domain type.

另一种是使用带注释的不基于域类型过滤事件的处理程序,声明一个处理程序。

To declare a handler, create a POJO and put the @RepositoryEventHandler annotation on it. This tells the BeanPostProcessor that this class needs to be inspected for handler methods.

创建一个POJO方法并添加@RepositoryEventHandler注解,这样可以告诉BeanPostProcessor这个class需要检查处理方法。

Once it finds a bean with this annotation, it iterates over the exposed methods and looks for annotations that correspond to the event you’re interested in. For example, to handle `BeforeSaveEvent`s in an annotated POJO for different kinds of domain types, you’d define your class like this:

一旦发现一点关于它的注释就遍历无遮蔽的方法。比如在注释POJO不同域类型处理Before save events,你可以像这样来定义你的类。

@RepositoryEventHandler (1)
public class PersonEventHandler {

  @HandleBeforeSave
  public void handlePersonSave(Person p) {
    // … you can now deal with Person in a type-safe way
  }

  @HandleBeforeSave
  public void handleProfileSave(Profile p) {
    // … you can now deal with Profile in a type-safe way
  }
}
1 It’s possible to narrow the types this handler applies against by using @RepositoryEventHandler(Person.class).
2 通过使用此处理程序是有可能来缩小适用于的类型的。 @RepositoryEventHandler(Person.class)

The domain type whose events you’re interested in is determined from the type of the first parameter of the annotated methods.

您感兴趣的域类型是从注释方法的第一个参数的类型确定的。

To register your event handler, either mark the class with one of Spring’s @Component stereotypes so it can be picked up by @SpringBootApplication or @ComponentScan. Or declare an instance of your annotated bean in your ApplicationContext. Then the BeanPostProcessor that is created in RepositoryRestMvcConfiguration will inspect the bean for handlers and wire them to the correct events.

注册事件处理程序,或标记一个有Springs的类有成分的刻板印象可以通过 @Component stereotypes so it can be picked up by @SpringBootApplication or @ComponentScan. Or declare an instance of your annotated bean in your ApplicationContext. Then the BeanPostProcessor that is created in RepositoryRestMvcConfiguration 或者说你在你的注释Bean的实例应用然后建立在RepositoryRestMvcConfiguration将检查Bean的处理程序和连接到正确的事件。

@Configuration
public class RepositoryConfiguration {

  @Bean
  PersonEventHandler personEventHandler() {
    return new PersonEventHandler();
  }
}
Spring Data REST events are customized Spring application events. Spring events are synchronous by default, unless they get republished across a boundary (like issuing a WebSocket event or crossing into a thread).
Spring Data Rest事件是定制的Spring 应用事件。Spring事件是同步的默认情况下,除非他们得到再版跨越边界(如发行一个WebSocket事件或进入一个线程)。

Integration

This section details various ways to integrate with Spring Data REST components, whether from a Spring application that is using Spring Data REST or from other means.

本节详细介绍了各种方法来与Spring Data Rest组成,无论是从一个使用Spring Data Rest 的Spring程序或者其他手段。

Sometimes you need to add links to exported resources in your own custom built Spring MVC controllers. There are three basic levels of linking available:

有时你需要添加链接到你自己的定制的Spring MVC控制器输出资源。有三个基本层次的连接可用:

  1. Manually assembling links

  2. Using Spring HATEOAS’s LinkBuilder with linkTo(), slash(), etc.

  3. Using Spring Data REST’s implementation of RepositoryEntityLinks.

  4. 手工装配环节

  5. 使用 Spring HATEOAS’s LinkBuilder with linkTo(), slash(), etc。

  6. 使用 Spring Data REST’s implementation of RepositoryEntityLinks

The first suggestion is terrible and should be avoided at all costs. It makes your code brittle and high risk. The second is handy when creating links to other hand written Spring MVC controllers. The last one, which you’ll see in a moment, is good for looking up resource links that are exported by Spring Data REST.

第一个建议是糟糕的,应该不惜一切代价避免。它使你的代码脆性和高风险。第二个是方便当创建链接到其他手写Spring MVC控制器。最后一个是你会在某个时刻看到使用Spring Data Rest输出的好的寻找资源的链接。

Assuming you have configured your code to use Spring’s autowiring,

假设您已配置了您的代码使用Spring的自动装配。

public class MyWebApp {

	private RepositoryEntityLinks entityLinks;

	@Autowired
	public MyWebApp(RepositoryEntityLinks entityLinks) {
		this.entityLinks = entityLinks;
	}
}

…​you can then use the following operations:

…​你可以使用以下步骤:

Table 5. 链接到导出资源的方法(Ways to link to exported resources)
Method Description

entityLinks.linkToCollectionResource(Person.class)

Provide a link to the collection resource of that type.

entityLinks.linkToSingleResource(Person.class, 1)

Provide a link to a single resource.

entityLinks.linkToPagedResource(Person.class, new PageRequest(…​))

Provide a link to a paged resource.

entityLinks.linksToSearchResources(Person.class)

Provides a list of links for all the finder methods exposed by the corresponding repository.

entityLinks.linkToSearchResource(Person.class, "findByLastName")

Provide a finder link by rel, i.e. the name of the finder.

All of the search-based links support extra parameters for paging and sorting. Checkout RepositoryEntityLinks for specifics. There is also linkFor(Class<?> type), but that returns a Spring HATEOAS LinkBuilder, which returns you to the lower level API. Try to use the other ones first.
所有的基于搜索的链接支持额外的参数进行分页和排序。校验 [RepositoryEntityLinks](http://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.html) for specifics.他还会 linkFor(Class<?> type), 但是返回 a Spring HATEOAS LinkBuilder, 和较低级别的api,也可以尝试用用其他的

Metadata

This section details the various forms of metadata provided by a Spring Data REST-based application.

本节详细介绍了基于Spring Data Rest为基础的应用程序提供的各种形式的元数据。

Application-Level Profile Semantics (ALPS)

ALPS is a data format for defining simple descriptions of application-level semantics, similar in complexity to HTML microformats. An ALPS document can be used as a profile to explain the application semantics of a document with an application-agnostic media type (such as HTML, HAL, Collection+JSON, Siren, etc.). This increases the reusability of profile documents across media types.
— M. Admundsen / L. Richardson / M. Foster
http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00
ALPS 和HTMl有着相同复杂性的微格式,一个ALPS文件可以作为一个剖面解释与应用无关的媒体类型文件的应用程序的语义(如HTML,hal,Collection+JSON,Siren,等)。 这增加了跨媒体类型的配置文件的可重用性。
— M. Admundsen / L. Richardson / M. Foster
http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00

Spring Data REST provides an ALPS document for every exported repository. It contains information about both the RESTful transitions as well as the attributes of each repository.

Spring Data REST provides an ALPS 为每一个导出的存储库提供一个ALPS文档,它包含了两个关于平安转换的信息以及各库的属性。

At the root of a Spring Data REST app is a profile link. Assuming you had an app with both persons and related addresses, the root document would look like this:

Spring Data Rest的应用程序的根是一个配置文件链接,假设你有一个应用程序与两个人相关的地址,根文件将看起来像这样:

{
  "_links" : {
    "persons" : {
      "href" : "http://localhost:8080/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/addresses"
    },
    "profile" : {
      "href" : "http://localhost:8080/profile"
    }
  }
}

A profile link, as defined in RFC 6906, is a place to include application level details. The ALPS draft spec is meant to define a particular profile format which we’ll explore further down in this section.

一个 profile 链接,比如 [RFC 6906](https://tools.ietf.org/html/rfc6906), 是包括应用层面相关内容的地方。[ALPS draft spec](http://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00) ALPS草案风格是为了定义一个特定的配置文件格式, 我们将在这一部分进一步探讨。

If you navigate into the profile link at localhost:8080/profile, you would see something like this:

如果你浏览到本地主机的 profile 链接 localhost:8080/profile,你将会看到这些:

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/profile"
    },
    "persons" : {
      "href" : "http://localhost:8080/profile/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/profile/addresses"
    }
  }
}
At the root level, profile is a single link and hence can’t handle serving up more than one application profile. That is why you must navigate to /profile to find a link for each resource’s metadata.
在根级别,profile是单链路,因此无法处理多个应用程序的配置文件。这就是为什么找到每个资源的元数据的链接你必须导航到/ profile

Let’s navigate to /profile/persons and look at the profile data for a Person resource.

让我们导航到 /profile/persons 看看个人资源的配置文件数据 Person 资源.

{
  "version" : "1.0",
  "descriptors" : [ {
    "id" : "person-representation", (1)
    "descriptors" : [ {
      "name" : "firstName",
      "type" : "SEMANTIC"
    }, {
      "name" : "lastName",
      "type" : "SEMANTIC"
    }, {
      "name" : "id",
      "type" : "SEMANTIC"
    }, {
      "name" : "address",
      "type" : "SAFE",
      "rt" : "http://localhost:8080/profile/addresses#address"
    } ]
  }, {
    "id" : "create-persons", (2)
    "name" : "persons", (3)
    "type" : "UNSAFE", (4)
    "rt" : "#person-representation" (5)
  }, {
    "id" : "get-persons",
    "name" : "persons",
    "type" : "SAFE",
    "rt" : "#person-representation"
  }, {
    "id" : "delete-person",
    "name" : "person",
    "type" : "IDEMPOTENT",
    "rt" : "#person-representation"
  }, {
    "id" : "patch-person",
    "name" : "person",
    "type" : "UNSAFE",
    "rt" : "#person-representation"
  }, {
    "id" : "update-person",
    "name" : "person",
    "type" : "IDEMPOTENT",
    "rt" : "#person-representation"
  }, {
    "id" : "get-person",
    "name" : "person",
    "type" : "SAFE",
    "rt" : "#person-representation"
  } ]
}
1 At the top is a detailed listing of the attributes of a Person resource, identified as #person-representation. It lists the names of the attributes.
2 After the resource representation are all the supported operations. This one is how to create a new Person.
3 The name is persons, which indicates that a POST should be applied to the whole collection, not a single person.
4 The type is UNSAFE because this operation can alter the state of the system.
5 顶部是一个详细的个人资源属性的列表 Person 确定为 #person-representation. 它列出属性的名称。
6 在资源表示后,所有支持的操作。折是如何创造一个新的 Person
7 这个名字是 persons, 这表明一个帖子应该适用于整个集合,而不是一个单一的 person
8 这种typeUNSAFE 因为这种操作可以改变系统的状态。
This JSON document has a media type of application/alps+json. This is different than the previous JSON document, which had a media type of application/hal+json. These formats are different and governed by different specs.
这个JSON文档有一个 application/alps+json. 这是不同于以往的JSON文档,其中有一个 application/hal+json.这些格式是不同的,受不同的规格。

You will also find a "profile" link shown in the collection of _links when you are looking at a collection resource.

你将找到一个 "profile" 在收集显示链接时,你看到的是一个收集资源。_links when you are looking at a collection resource.

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons" (1)
    },
    ... other links ...
    "profile" : {
      "href" : "http://localhost:8080/profile/persons" (2)
    }
  },
  ...
}
1 This HAL document respresents the Person collection.
2 It has a profile link to the same URI for metadata.
3 这个HAl文件代表 Person 收藏。
4 它有一个 profile 链接到同一个URI元数据。

The profile link, again, will serve up ALPS by default or if you use an Accept header of application/alps+json.

The profile link,如果你使用一个接受应用程序/ALPS+ JSON的标头,ALPS默认将再次服务配置文件链接。http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1[Accept header] of application/alps+json

Hypermedia control types

ALPS displays types for each hypermedia control. They include:

ALPS显示每个超媒体控件的类型,他们包括:

Table 6. ALPS types
Type Description

SEMANTIC

A state element (e.g. HTML.SPAN, HTML.INPUT, etc.).

SAFE

A hypermedia control that triggers a safe, idempotent state transition (e.g. GET or HEAD).

IDEMPOTENT

A hypermedia control that triggers an unsafe, idempotent state transition (e.g. PUT or DELETE).

UNSAFE

A hypermedia control that triggers an unsafe, non-idempotent state transition (e.g. POST).

In the representation section up above, bits of data from the application are marked SEMANTIC. The address field is a link that involves a safe GET to retrive. Hence, it is marked SAFE. Hypermedia operations themselves map onto the types as shown the table.

在上面的表示部分中,从应用程序的数据的bits被标记为SEMANTICaddress字段是涉及安全GET能够利用的链接。因此,它被标记为SAFE。超媒体操作本身映射到所显示的表的类型。

ALPS with Projections

If you define any projections, they are also listed in the ALPS metadata. Assuming we also defined inlineAddress and noAddresses, they would appear inside the relevant operations, i.e. GET for the whole collection as well GET for a single resource. The following shows the alternate version of the get-persons subsection:

如果您定义了任何Projections,他们也将在ALPS元数据中列出。假设我们还定义了 inlineAddressnoAddresses 相关的内部操作。即 GET 整个集合以及GET 为一个单一的资源。下面显示了get-persons的另一个版本:

...
  {
    "id" : "get-persons",
    "name" : "persons",
    "type" : "SAFE",
    "rt" : "#person-representation",
    "descriptors" : [ { (1)
      "name" : "projection",
      "doc" : {
        "value" : "The projection that shall be applied when rendering the response. Acceptable values available in nested descriptors.",
        "format" : "TEXT"
      },
      "type" : "SEMANTIC",
      "descriptors" : [ {
        "name" : "inlineAddress", (2)
        "type" : "SEMANTIC",
        "descriptors" : [ {
          "name" : "address",
          "type" : "SEMANTIC"
        }, {
          "name" : "firstName",
          "type" : "SEMANTIC"
        }, {
          "name" : "lastName",
          "type" : "SEMANTIC"
        } ]
      }, {
        "name" : "noAddresses", (3)
        "type" : "SEMANTIC",
        "descriptors" : [ {
          "name" : "firstName",
          "type" : "SEMANTIC"
        }, {
          "name" : "lastName",
          "type" : "SEMANTIC"
        } ]
      } ]
    } ]
  }
...
1 A new attribute, descriptors, appears containing an array with one entry, projection.
2 Inside the projection.descriptors we can see inLineAddress listed. It will render address, firstName, and lastName. Relationships rendered inside a projection result in inlining the data fields.
3 Also found is noAddresses, which serves up a subset containing firstName and lastName.
4 一个新的属性, descriptors,描述符包含了一个数组的投影。projection
5 里面的 projection.descriptors我们能看见inLineAddress 这将使 address, firstName,和 lastName. 呈现在投影结果在内联数据字段的关系。
6 在这里发现 noAddresses,它提供了一个子集 firstNamelastName

With all this information, a client should be able to deduce not only the RESTful transitions avaiable, but also, to some degree, the data elements needed to interact.

用所有这些信息,客户端不仅能够推断RESTful转换可用,而且,在一定程度上,所需的数据元素可以进行交互。

给你的ALPS描述添加自定义细节(Adding custom details to your ALPS descriptions)

It’s possible to create custom messages that appear in your ALPS metadata. Just create rest-messages.properties like this:

在你的ALPS的元数据可以创建自定义的消息。创建rest-messages.properties 就像这样:

rest.description.person=A collection of people
rest.description.person.id=primary key used internally to store a person (not for RESTful usage)
rest.description.person.firstName=Person's first name
rest.description.person.lastName=Person's last name
rest.description.person.address=Person's address

As you can see, this defines details to display for a Person resource. They alter the ALPS format of the person-representation as follows:

正如你所看到的,这定义了一个用于显示 Person的详细信息。它们改变ALPS的* person-representation *格式如下:

...
  {
    "id" : "person-representation",
    "doc" : {
      "value" : "A collection of people", (1)
      "format" : "TEXT"
    },
    "descriptors" : [ {
      "name" : "firstName",
      "doc" : {
        "value" : "Person's first name", (2)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "lastName",
      "doc" : {
        "value" : "Person's last name", (3)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "id",
      "doc" : {
        "value" : "primary key used internally to store a person (not for RESTful usage)", (4)
        "format" : "TEXT"
      },
      "type" : "SEMANTIC"
    }, {
      "name" : "address",
      "doc" : {
        "value" : "Person's address", (5)
        "format" : "TEXT"
      },
      "type" : "SAFE",
      "rt" : "http://localhost:8080/profile/addresses#address"
    } ]
  }
...

By supplying these property settings, each field has an extra doc attribute.

通过提供的属性设置,每个字段有一个额外的 doc 属性。

1 The value of rest.description.person maps into the whole representation.
2 The value of rest.description.person.firstName maps to the firstName attribute.
3 The value of rest.description.person.lastName maps to the lastName attribute.
4 The value of rest.description.person.id maps to the id attribute, a field not normally displayed.
5 The value of rest.description.person.address maps to the address attribute.
Spring MVC (which is the essence of a Spring Data REST application) supports locales, meaning you can bundle up multiple properties files with different messages.
Spring MVC(这是Spring Data REST应用的本质)本地化支持,意味着你可以把多个属性文件与不同的消息整合到一起。

JSON Schema

JSON Schema is another form of metadata supported by Spring Data REST. Per their website, JSON Schema has the following advantages:

  • describes your existing data format

  • clear, human- and machine-readable documentation

  • complete structural validation, useful for automated testing and validating client-submitted data

  • 描述您现有的数据格式

  • 人类和机器清晰可读的文件

  • 完整的结构验证,有助于自动化测试和验证客户端提交的数据

As shown in the previous section, you can reach this data by navigating from the root URI to the "profile" link.

previous section所示,如果你的资源有链接到其他资源,会有更多的细节。你也将找到一个"profile" 链接.

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/profile"
    },
    "persons" : {
      "href" : "http://localhost:8080/profile/persons"
    },
    "addresses" : {
      "href" : "http://localhost:8080/profile/addresses"
    }
  }
}

These links are the same as shown earlier. To retrieve JSON Schema you invoke them with Accept header application/schema+json.

这些链接是按照上面提到的一样。要检索JSON Schema调用他的Accept header application/schema+json

In this case, if you executed curl -H 'Accept:application/schema+json' http://localhost:8080/profile/persons, you would see something like this:

在这种情况下,如果执行curl -H 'Accept:application/schema+json' http://localhost:8080/profile/persons,你会看到这样的内容:

{
  "title" : "org.springframework.data.rest.webmvc.jpa.Person", (1)
  "properties" : { (2)
    "firstName" : {
      "readOnly" : false,
      "type" : "string"
    },
    "lastName" : {
      "readOnly" : false,
      "type" : "string"
    },
    "siblings" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "uri"
    },
    "created" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "date-time"
    },
    "father" : {
      "readOnly" : false,
      "type" : "string",
      "format" : "uri"
    },
    "weight" : {
      "readOnly" : false,
      "type" : "integer"
    },
    "height" : {
      "readOnly" : false,
      "type" : "integer"
    }
  },
  "descriptors" : { },
  "type" : "object",
  "$schema" : "http://json-schema.org/draft-04/schema#"
}
1 The type that was exported
2 A listing of properties
3 被导出的类型
4 属性的列表

There are more details if your resources have links to other resources.

还有更多的细节,如果你的资源有其他资源的链接。

You will also find a "profile" link shown in the collection of _links when you are looking at a collection resource.

你还会在_links的资源集合显示时发现一个"profile"链接。

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/persons" (1)
    },
    ... other links ...
    "profile" : {
      "href" : "http://localhost:8080/profile/persons" (2)
    }
  },
  ...
}
1 This HAL document respresents the Person collection.
2 It has a profile link to the same URI for metadata.
3 此HAL文档代表了 Person 集合。
4 它有一个 profile 链接元数据相同的URL。

The profile link, again, will serve up ALPS by default. If you supply it with an Accept header of application/schema+json, it will render the JSON Schema representation.

这个profile 链接,在默认情况下成为了ALPS。如果您用http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1[Accept header]为application/schema+json请求,它就会以JSON Schema呈现。

安全(Security)

Spring Data REST works quite well with Spring Security. This section will show examples of how to secure your Spring Data REST services with method level security.

Spring Data REST 与 Spring Security 是很有用的。本节将展示如何保护你的Spring Data REST 服务的例子与 “方法级安全性”。

安全之前和安全之后(@Pre and @Post security)

The following example from Spring Data REST’s test suite shows Spring Security’s PreAuthorization model, the most sophisticated version:

下面的例子从Spring Data REST测试套件的数据显示了Spring Security的PreAuthorization模型[PreAuthorization model](http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#el-pre-post-annotations),最复杂的版本:

Example 5. spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc//security/PreAuthorizedOrderRepository.java

This is a standard Spring Data repository definition extending CrudRepository with some key changes.

这个标准的Spring Data资源库定义扩展 CrudRepository 有一些关键的变化。

1 This Spring Security annotation secures the entire repository. The Spring Security SpEL expression indicates the principal must have ROLE_USER in his collection of roles.
2 To change method-level settings, you must override the method signature and apply a Spring Security annotation. In this case, the method overrides the repository-level settings with the requirement that the user have ROLE_ADMIN to perform a delete.
3 这个Spring Security注释保护整个存储库。http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#el-common-built-in[Spring Security SpEL expression] 表明在principal中,他的角色的集合必须有ROLE_USER.
4 要更改方法级设置,您必须覆盖方法签名并应用一个Spring Security注释。在这种情况下,该方法覆盖储存库层次的设置与要求用户ROLE_ADMIN执行删除。不要结合存储库和方法级安全性设置。相反,方法级设置覆盖库级方法级设置。
Repository and method level security settings don’t combine. Instead, method-level settings override repository level settings.
资源库和方法级的安全设置不结合。相反,override资源库方法级别的设置。

The previous example illustrates that CrudRepository, in fact, has four delete methods. You must override all delete methods to properly secure it.

前面的例子说明CrudRepository,事实上,有四个删除方法。你必须覆盖所有正确安全的删除方法。

@Secured security

The following example shows Spring Security’s older @Secured annotation, which is purely role-based:

下面的例子展示了Spring Security @ secure注解,纯粹是基于角色:

Example 6. spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc//security/SecuredPersonRepository.java
1 This results in the same security check, but has less flexibility. It only allows roles as the means to restrict access.
2 Again, this shows that delete methods require ROLE_ADMIN.
3 这个结果在相同的安全检查,但有更少的灵活性。它只允许角色意味着限制访问。
4 再一次,这表明需要ROLE_ADMIN删除方法。
If you are starting with a new project or first applying Spring Security, @PreAuthorize is the recommended solution. If are already using Spring Security with @Secured in other parts of your app, you can continue on that path without rewriting everything.
如果你开始一个新项目或应用Spring Security,@PreAuthorize是推荐的解决方案。如果已经使用Spring Security @ secure在应用程序的其他部分,你可以继续在这条道路上,而且不会重写任何的东西。

启用方法级安全性(Enabling method level security)

To configure method level security, here is a brief snippet from Spring Data REST’s test suite:

配置方法级安全性,这里是一个简短的片段来自Spring Data REST测试套件的数据:

Example 7. spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc//security/SecurityConfiguration.java
	...
}
1 This is a Spring configuration class.
2 It uses Spring Security’s @EnableGlobalMethodSecurity annotation to enable both @Secured and @Pre/@Post support. NOTE: You don’t have to use both. This particular case is used to prove both versions work with Spring Data REST.
3 This class extends Spring Security’s WebSecurityConfigurerAdapter which is used for pure Java configuration of security.
4 这是一个Spring配置类。
5 它使用Spring Security @EnableGlobalMethodSecurity注释使@ secure和@Pre / @Post支持。注意:您不需要使用。这种特殊情况下用来证明两个版本使用 Spring Data REST。
6 这个类扩展Spring Security WebSecurityConfigurerAdapter用于纯Java的安全配置。

The rest of the configuration class isn’t listed because it follows standard practices you can read about in the Spring Security reference docs.

其余的配置类不列出,因为它遵循标准实践中可以读到 standard practices你可以读到Spring Security参考文档。

工具(Tools)

HAL 浏览器(The HAL Browser)

The developer of the HAL spec has a useful application: the HAL Browser. It’s a web app that stirs in a little HAL-powered JavaScript. You can point it at any Spring Data REST API and use it to navigate the app and create new resources.

HAL spec的开发者有一个实用的应用程序:[HAL Browser](https://github.com/mikekelly/hal-browser)。这是一个带有一点HAL-powered JavaScript的web应用程序。 你可以在任何Spring Data REST API中使用它来导航应用程序和创建新的资源。

Instead of pulling down the files, embedding them in your application, and crafting a Spring MVC controller to serve them up, all you need to do is add a single dependency.

拉取这个文件,嵌入在应用程序中,并制定一个Spring MVC控制器服务,所有您需要做的就是添加一个依赖项。

In Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-rest-hal-browser</artifactId>
    </dependency>
</dependencies>

In Gradle:

dependencies {
    compile 'org.springframework.data:spring-data-rest-hal-browser'
}
If you use Spring Boot or the Spring Data BOM (bill of materials), you don’t need to specify the version.
如果你使用 Spring Boot或 Spring Data BOM(材料清单),您不需要指定版本。

This dependency will autoconfigure the HAL Browser to be served up when you visit your application’s root URI in a browser. (NOTE: http://localhost:8080 was plugged into the browser, and it redirect to the URL shown below.)

当你在浏览器访问应用程序的根URI时HAL Browser将根据这种依赖自动配置。(NOTE: http://localhost:8080 键入浏览器,它重定向到如下所示的URL)。

hal browser 1.png

The screen shot above shows the root path of the API. On the right side are details from the response including headers and the body (a HAL document).

上面的屏幕截图显示了API的根路径。右边是细节从响应包括头部和正文(HAL文档)。

The HAL Browser reads the links from the response and puts them on a list on the left side. You can either click on the GET button and navigate to one of the collections, or click on the non-GET option to make changes.

HAL Browser读取响应的链接,并在左边列表。你可以点击的按钮,导航到一个集合,或者点击non-GET选项来更改。

The HAL Browser speaks URI Template. You may notice up above the GET button next to persons has a question mark icon. An expansion dialog will pop-up if you choose to navigate to it like this:

HAL Browser拼写URI Template。你可能会注意到上面得到按钮旁边的人有一个问号图标。如果你点击这个图标,对话框将会这样弹出:

hal browser 3.png

If you click Follow URI without entering anything, the variables will essentially be ignored. For situations like 预测和摘要(Projections and Excerpts) or 分页和排序(Paging and Sorting), this can be useful.

如果你点击Follow URI没有任何事情可做,变量会被忽略。对于像预测和摘要(Projections and Excerpts)分页和排序(Paging and Sorting),这可能是有用的情况。。

When you click on a non-GET button, a pop-up dialog appears. By default, it shows POST. This field can be adjusted to either PUT or PATCH. The headers are filled out to properly to submit a new JSON document.

当你点击一个non-GET按钮,会出现一个弹出对话框。默认情况下,它显示POST。这个字段可以调整为PUTPATCH。正确填写headers提交一个新的JSON文档。

Below the URI, method, and headers are the fields. These are automatically supplied based on the metadata of the resources, automatically generated by Spring Data REST. Update your domain objects, and the pop-up will reflect it.

以下URI,方法,和headers字段。这些都是自动提供基于资源的元数据,通过Spring Data REST自动生成。更新您的域对象,将弹出反应。

hal browser 2.png

定制Spring Data REST(Customizing Spring Data REST)

There are many options to tailor Spring Data REST. These subsections show how.

有许多选项来定制Spring Data REST.这些部分展示。

定制项目资源URIs(Customizing item resource URIs)

By default the URI for item resources are comprised of the path segment used for the collection resource with the database identifier appended. That allows us to use the repository’s findOne(…) method to lookup entity instances. As of Spring Data REST 2.5 this can be customized by using configuration API on RepositoryRestConfiguration (preferred on Java 8) or by registering an implementation of EntityLookup as Spring bean in your application. Spring Data REST will pick those up and tweak the URI generation according to their implementation.

默认情况下,项目资源的URI路径段组成的用于收集附加资源与数据库标识符。允许我们使用存储库的findOne(…)方法来查找实体实例。作为Spring Data REST2.5可以通过使用自定义配置API RepositoryRestConfiguration(首选Java 8)或通过注册EntityLookup为Spring bean的实现您的应用程序。 Spring Data REST会挖掘和调整那些URI根据他们的实现。

Assume a User with a username property that uniquely identifies it. Also, assume we have a method Optional<User> findByUsername(String username) on the according repository.

假设一个用户用户名属性,唯一地标识。同时,假设我们有一个方法“Optional<User>findByUsername”(String username)根据存储库.

On Java 8 we can simply register the mapping methods as method references to weak the URI creation as follows:

在Java 8中我们可以简单地注册如同映射法,URI引用创建方法如下:

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {

    config.withCustomEntityLookup().//
      forRepository(UserRepository.class, User::getUsername, UserRepository::findByUsername);
  }
}

forRepository(…) takes the repository type as first argument a method reference mapping the repositories domain type to some target type, as well as another method reference to map that value back using the repository mentioned as first argument.

forRepository(…)存储库类型作为第一个参数方法引用存储库域类型映射到一些目标类型,以及另一个方法引用映射值使用存储库提到作为第一个参数。

If you’re not running Java 8 or better, you could use the method but it would require a few quite verbose anonymous inner classes to be use. That’s why on older Java versions you probably prefer implementing a UserEntityLookup looking like this:

如果你不运行Java 8或你可以使用更好的方法,但需要一些非常详细的使用匿名内部类。这就是为什么你可能更喜欢在旧的Java版本实现UserEntityLookup看起来像这样:

@Component
public class UserEntityLookup extends EntityLookupSupport<User> {

    private final UserRepository repository;

    public UserEntityLookup(UserRepository repository) {
        this.repository = repository;
    }

    @Override
    public Serializable getResourceIdentifier(User entity) {
        return entity.getUsername();
    }

    @Override
    public Object lookupEntity(Serializable id) {
        return repository.findByUsername(id.toString());
    }
}

Note, how getResourceIdentifier(…) returns the username to be used by the URI creation. To load entity instances by the value returned from that method we now implement lookupEntity(…) using the query method available on the UserRepository.

注意,getResourceIdentifier(…)返回用户名使用的URI。加载实体实例方法的返回值从我们现在实现lookupEntity(…)使用UserRepository上可用的查询方法。

配置REST URL路径(Configuring the REST URL path)

Configuring the segments of the URL path under which the resources of a JPA repository are exported is simple. You just add an annotation at the class level and/or at the query method level.

配置的URL路径下JPA库出口的资源很简单。你只需要添加一个注解在类级别和/或查询方法级别。

By default, the exporter will expose your CrudRepository using the name of the domain class. Spring Data REST also applies the Evo Inflector to pluralize this word. So a repository defined as follows:

默认情况下,出口商将公开CrudRepository使用域类的名称。Spring Data REST 也适用于https://github.com/atteo/evo-inflector[Evo Inflector]去兼职这个词。所以存储库定义如下:

interface PersonRepository extends CrudRepository<Person, Long> {}

Will, by default, be exposed under the URL http://localhost:8080/persons/

默认情况下,暴露在URL`http://localhost:8080/persons/`

To change how the repository is exported, add a @RestResource annotation at the class level:

改变存储库导出,在类级别添加一个@RestResource注解:

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {}

Now the repository will be accessible under the URL: http://localhost:8080/people/

现在可访问存储库URL下: http://localhost:8080/people/

If you have query methods defined, those also default to be exposed by their name:

如果您定义了查询方法,这些也默认暴露他们的名字:

interface PersonRepository extends CrudRepository<Person, Long> {

  List<Person> findByName(String name);
}

This would be exposed under the URL: http://localhost:8080/persons/search/findByName

All query method resources are exposed under the resource search.
所有资源被暴露在search的查询方法上。

To change the segment of the URL under which this query method is exposed, use the @RestResource annotation again:

改变这个查询的部分URL的方法暴露,再次使用@RestResource注解:

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names")
  List<Person> findByName(String name);
}

Now this query method will be exposed under the URL: http://localhost:8080/people/search/names

现在这个查询方法将会暴露在URL:`http://localhost:8080/people/search/names`

处理rels(Handling rels)

Since these resources are all discoverable, you can also affect how the "rel" attribute is displayed in the links sent out by the exporter.

因为这些资源都可发现,还可以在出口处影响显示在链接发出的"rel"属性。

For instance, in the default configuration, if you issue a request to http://localhost:8080/persons/search to find out what query methods are exposed, you’ll get back a list of links:

例如,在默认的配置,如果你发出一个请求 http://localhost:8080/persons/search 找出查询方法暴露,你会得到一个链接列表:

{
  "_links" : {
    "findByName" : {
      "href" : "http://localhost:8080/persons/search/findByName"
    }
  }
}

To change the rel value, use the rel property on the @RestResource annotation:

改变rel值,使用rel属性@RestResource注解:

@RepositoryRestResource(path = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names", rel = "names")
  List<Person> findByName(String name);
}

This would result in a link value of:

这将产生一个这样值的链接:

{
  "_links" : {
    "names" : {
      "href" : "http://localhost:8080/persons/search/names"
    }
  }
}
These snippets of JSON assume you are using Spring Data REST’s default format of HAL. It’s possible to turn off HAL, which would cause the output to look different. But your ability to override rel names is totally independent of the rendering format.
假设你正在使用 Spring Data REST的默认http://stateless.co/hal_specification.html[HAL]格式的JSON片段。可能关掉HAL,这将导致输出看起来不同。但是你覆盖rel名字的能力是完全独立的呈现格式。
@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(path = "names", rel = "names")
  List<Person> findByName(String name);
}

Altering the rel of a Repository changes the top level name:

改变存储库的rel改变了顶级名称:

{
  "_links" : {
    "people" : {
      "href" : "http://localhost:8080/people"
    },
    …
  }
}

In the top level fragment above:

在上面的顶级片段:

  • path = "people" changed the value in href from /persons to /people

  • rel = "people" changed the name of that link from persons to people

When you navigate to the search resource of this repository, the finder-method’s @RestResource annotation has altered the path as shown below:

当您导航到这个库的搜索资源,查找器的方法@RestResource注解已经改变了路径如下所示:

{
  "_links" : {
    "names" : {
      "href" : "http://localhost:8080/people/search/names"
    }
  }
}

This collection of annotations in your Repository definition has caused the following changes:

这个集合的注解存储库定义了以下变化:

  • The Repository-level annotation’s path = "people" is reflected in the base URI with /people

  • Being a finder method provides you with /people/search

  • path = "names" creates a URI of /people/search/names

  • rel = "names" changes the name of that link from findByNames to names

隐藏某些存储库,查询方法或字段(Hiding certain repositories, query methods, or fields)

You may not want a certain repository, a query method on a repository, or a field of your entity to be exported at all. Examples include hiding fields like password on a User object or similar sensitive data. To tell the exporter to not export these items, annotate them with @RestResource and set exported = false.

你可能不希望得到某些资源库,资源库的查询方法,或者实体导出字段。例如包含像用户密码隐藏字段对象或类似的敏感数据。使用 @RestResource 注解并设置exported = false不导出这些东西.

For example, to skip exporting a Repository:

例如,跳过导出一个资源库:

@RepositoryRestResource(exported = false)
interface PersonRepository extends CrudRepository<Person, Long> {}

To skip exporting a query method:

跳过导出查询方法:

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @RestResource(exported = false)
  List<Person> findByName(String name);
}

Or to skip exporting a field:

或跳过导出字段:

@Entity
public class Person {

  @Id @GeneratedValue private Long id;

  @OneToMany
  @RestResource(exported = false)
  private Map<String, Profile> profiles;
}
Projections provide the means to change what is exported and effectively side step these settings. If you create any projections against the same domain object, it’s your responsiblity to NOT export the fields. See
Projections提供了改变这些导出和有效设置的手段side step these settings。如果你创建任何针对相同的域对象的projections,这是你不导出字段的责任。

隐藏CRUD的方法(Hiding repository CRUD methods)

If you don’t want to expose a save or delete method on your CrudRepository, you can use the @RestResource(exported = false) setting by overriding the method you want to turn off and placing the annotation on the overriden version. For example, to prevent HTTP users from invoking the delete methods of CrudRepository, override all of them and add the annotation to the overriden methods.

如果你不想公开CrudRepository保存或删除方法,您可以使用@RestResource(exported= false)把你想关掉和注解放在重载版本通过重写方法设置.例如,防止用户HTTP调用CrudRepository的删除方法,覆盖所有,将注释添加到重载方法。

@RepositoryRestResource(path = "people", rel = "people")
interface PersonRepository extends CrudRepository<Person, Long> {

  @Override
  @RestResource(exported = false)
  void delete(Long id);

  @Override
  @RestResource(exported = false)
  void delete(Person entity);
}
It is important that you override both delete methods as the exporter currently uses a somewhat naive algorithm for determing which CRUD method to use in the interest of faster runtime performance. It’s not currently possible to turn off the version of delete which takes an ID but leave exported the version that takes an entity instance. For the time being, you can either export the delete methods or not. If you want turn them off, then just keep in mind you have to annotate both versions with exported = false.
重要的是,你覆盖和删除的方法作为导出当前使用的少量简单算法决定使用哪个CRUD方法有更快的运行时性能。当前是不可能去关闭版本和删除一个ID,但离开导出需要一个实体实例。暂时,您可以导出删除方法或不导出。如果你想关闭他们,那么就记住你必须对两个版本的注解设置exported = false。

添加Spring Data REST到一个现有的Spring MVC应用程序(Adding Spring Data REST to an existing Spring MVC Application)

The following steps are unnecessary if you are using Spring Boot. Adding spring-boot-starter-data-rest will cause it to automatically to get added to your application.
以下步骤是不必要的,如果你使用的是 Spring Boot。添加spring-boot-starter-data-rest将导致它自动添加到您的应用程序。

If you have an existing Spring MVC application and you’d like to integrate Spring Data REST, it’s actually very easy.

如果你有一个现有的Spring MVC应用程序并且你想整合Spring Data REST,其实很容易。

Somewhere in your Spring MVC configuration (most likely where you configure your MVC resources) add a bean reference to the JavaConfig class that is responsible for configuring the RepositoryRestController. The class name is org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration.

在你的Spring MVC结构的地方(最可能在你配置你的MVC资源)的javaconfig类负责配置repositoryrestcontroller添加bean的引用。这个类名是 org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration.

In Java, this would look like:

在java中,这会看起来像:

import org.springframework.context.annotation.Import;
import org.springframework.data.rest.webmvc.RepositoryRestMvcConfiguration;

@Configuration
@Import(RepositoryRestMvcConfiguration.class)
public class MyApplicationConfiguration {

  …
}

In XML this would look like:

在XML中,这将看起来像:

<bean class="org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration"/>

When your ApplicationContext comes across this bean definition it will bootstrap the necessary Spring MVC resources to fully-configure the controller for exporting the repositories it finds in that ApplicationContext and any parent contexts.

当你的ApplicationContext遇到这个bean定义应用,他将引导必要的Spring MVC的控制器资源去充分配置导出库,它会找出和ApplicationContext相关的任何上下文。

更多关于所需配置(More on required configuration)

There are a couple Spring MVC resources that Spring Data REST depends on that must be configured correctly for it to work inside an existing Spring MVC application. We’ve tried to isolate those resources from whatever similar resources already exist within your application, but it may be that you want to customize some of the behavior of Spring Data REST by modifying these MVC components.

有很多的Spring MVC资源Spring Data REST取决于必须要在现有的Spring MVC应用工作的正确配置。我们试图隔离任何类似这些已经存在于你的应用程序的资源,但它可能是你想自定义的一些 Spring Data REST行为,通过修改这些MVC组件。

The most important things that we configure especially for use by Spring Data REST include:

我们配置和特别是使用Spring Data REST的重要的东西包括:

存储库的处理程序映射(RepositoryRestHandlerMapping)

We register a custom HandlerMapping instance that responds only to the RepositoryRestController and only if a path is meant to be handled by Spring Data REST. In order to keep paths that are meant to be handled by your application separate from those handled by Spring Data REST, this custom HandlerMapping inspects the URL path and checks to see if a Repository has been exported under that name. If it has, it allows the request to be handled by Spring Data REST. If there is no Repository exported under that name, it returns null, which just means "let other HandlerMapping instances try to service this request".

我们注册了一个自定义HandlerMapping的实例,只响应repositoryrestcontroller 的,如果路径是由Spring Data REST处理。为了保持由你的应用程序的数据处理路径,通过 Spring Data REST单独处理,这一方法HandlerMapping检查URL路径和检查是否一个库已经在那个名字出口。如果它有,它允许由Spring DATA REST处理的请求。如果没有库在那个名字出口,它返回null,这就意味着“让其他HandlerMapping的实例尝试服务这一要求”。

The Spring Data REST HandlerMapping is configured with order=(Ordered.LOWEST_PRECEDENCE - 100) which means it will usually be first in line when it comes time to map a URL path. Your existing application will never get a chance to service a request that is meant for a repository. For example, if you have a repository exported under the name "person", then all requests to your application that start with /person will be handled by Spring Data REST and your application will never see that request. If your repository is exported under a different name, however (like "people"), then requests to /people will go to Spring Data REST and requests to "/person" will be handled by your application.

Spring Data REST HandlerMapping的配置 order=(Ordered.LOWEST_PRECEDENCE - 100)这意味着它通常会被排在第一位的时候,映射的URL路径。你的现有应用程序的资源库将永远不会得到一个服务的请求。例如,如果你有一个名为“person”导出的资源库,那么所有启动的应用程序的请求都将由Spring Data REST处理,而你的应用程序将永远不会看到该请求。如果您的资源库被导出为一个不同的名称,尽管如此(如“person”),然后请求/people 将到Spring Data REST和请求“/person”将由你的应用程序处理。

覆盖Spring Data REST响应处理程序(Overriding Spring Data REST Response Handlers)

Sometimes you may want to write a custom handler for a specific resource. To take advantage of Spring Data REST’s settings, message converters, exception handling, and more, use the @RepositoryRestController annotation instead of a standard Spring MVC @Controller or @RestController:

有时,您可能希望为特定资源编写一个自定义处理程序。要利用Spring Data REST的设置,消息转换器,异常处理,和更多,使用@RepositoryRestController 注释代替标准的 Spring MVC @Controller or @RestController:

@RepositoryRestController
public class ScannerController {

    private final ScannerRepository repository;

    @Autowired
    public ScannerController(ScannerRepository repo) { (1)
        repository = repo;
    }

    @RequestMapping(method = GET, value = "/scanners/search/listProducers") (2)
    public @ResponseBody ResponseEntity<?> getProducers() {
        List<String> producers = repository.listProducers(); (3)

        //
        // do some intermediate processing, logging, etc. with the producers
        //

        Resources<String> resources = new Resources<String>(producers); (4)

        resources.add(linkTo(methodOn(ScannerController.class).getProducers()).withSelfRel()); (5)

        // add other links as needed

        return ResponseEntity.ok(resources); (6)
    }

}

This controller will be served from the same API base path defined in RepositoryRestConfiguration.setBasePath that is used by all other RESTful endpoints (e.g. /api). It also has these characteristics:

该控制器将是在RepositoryRestConfiguration.setBasePath由所有其他使用RESTful端点定义相同的API库路径(例如/ API)。它也有这些特点:

1 This example uses constructor injection.
2 This handler plugs in a custom handler for a Spring Data finder method.
3 This handler is using the underlying repository to fetch data, but will then do some form of post processing before returning the final data set to the client.
4 The results need to be wrapped up in a Spring HATEOAS Resources object to return a collection, but only a Resource for a single item.
5 Add a link back to this exact method as a "self" link.
6 Returning the collection using Spring MVC’s ResponseEntity wrapper ensure the collection is properly wrapped and rendered in the proper accept type.
7 这个例子使用构造函数注入。
8 此处理程序在一个用于弹簧数据查找器方法的自定义处理程序中插入。
9 该处理程序使用底层的存储库来获取数据,但在将最终的数据集返回到客户端之前,会做一些处理后的处理。
10 结果需要被包裹在一个Spring HATEOAS资源对象返回一个集合,但只有一个单一的项目资源。
11 添加一个链接返回到这个确切的方法作为一个“self”链接。
12 返回集合中使用Spring MVC的responseentity包装确保收集正确的包装和适当的渲染接受型。

Resources is for a collection while Resource is for a single item. These types can be combined. If you know the links for each item in a collection, use Resources<Resource<String>> (or whatever the core domain type is). This lets you assemble links for each item as well as for the whole collection.

资源是为一个集合,而资源是为一个单一项目。这些类型可以合并。如果你知道集合中的每个项目的链接,使用资源"<Resource<String>>" (或任何核心域类型).这可以让您为每个项目集合链接,以及为整个集合。

In this example, the combined path will be RepositoryRestConfiguration.getBasePath() + /scanners/search/listProducers.
在这个例子中,合并的路径将是 RepositoryRestConfiguration.getBasePath() + /scanners/search/listProducers

If you’re NOT interested in entity-specific operations but still want to build custom operations underneath basePath, such as Spring MVC views, resources, etc. use @BasePathAwareController.

如果你没有实体的具体操作感兴趣,但还是要建立自定义操作在修改表情,如Spring MVC视图、资源使用。@BasePathAwareController.

If you use @Controller or @RestController for anything, that code will be totally outside the scope of Spring Data REST. This extends to request handling, message converters, exception handling, etc.
如果你全部使用@ Controller@ RestController注解,该代码将完全在Spring Data REST的范围之内。这涉及到请求处理,消息变换器,异常处理,等。

定制的JSON输出(Customizing the JSON output)

Sometimes in your application you need to provide links to other resources from a particular entity. For example, a Customer response might be enriched with links to a current shopping cart, or links to manage resources related to that entity. Spring Data REST provides integration with Spring HATEOAS and provides an extension hook for users to alter the representation of resources going out to the client.

有时在您的应用程序中,您需要提供从一个特定实体的其他资源的链接。例如,一个客户响应可能会被丰富的链接到当前的购物车,或链接来管理与该实体相关的资源。Spring Data REST提供集成https://github.com/SpringSource/spring-hateoas[Spring HATEOAS]和为用户提供了客户端改变资源表达的扩展钩。

资源处理器接口(The ResourceProcessor interface)

Spring HATEOAS defines a ResourceProcessor<> interface for processing entities. All beans of type ResourceProcessor<Resource<T>> will be automatically picked up by the Spring Data REST exporter and triggered when serializing an entity of type T.

Spring HATEOAS定义了一个ResourceProcessor<>用于处理实体的接口。所有类型的类ResourceProcessor<Resource<T>> 将自动被Spring Data REST导出和触发一个T类型的实体的序列化。

For example, to define a processor for a Person entity, add a @Bean to your `ApplicationContext like the following (which is taken from the Spring Data REST tests):

例如,定义为一个人的实体处理器,在你的ApplicationContext添加一个@Bean如下(这是从 Spring Data REST测试拿的):

@Bean
public ResourceProcessor<Resource<Person>> personProcessor() {

   return new ResourceProcessor<Resource<Person>>() {

     @Override
     public Resource<Person> process(Resource<Person> resource) {

      resource.add(new Link("http://localhost:8080/people", "added-link"));
      return resource;
     }
   };
}
This example hard codes a link to http://localhost:8080/people. If you have a Spring MVC endpoint inside your app that you wish to link to, consider using Spring HATEOAS’s linkTo(…​) method to avoid managing the URL.

这个例子硬编码链接到http://localhost:8080/people如果你有一个Spring MVC的端点在你的应用程序,你要连接,可以考虑使用Spring HATEOAS’s linkTo(…​)避免管理网址的方法。

It’s possible to add links to the default representation of an entity by simply calling resource.add(Link) like the example above. Any links you add to the Resource will be added to the final output.

通过简单的调用资源,可以添加一个实体的默认表示的链接。如上面的例子添加(链接)。任何您添加到资源的链接都将被添加到最终输出中。

定制的表示(Customizing the representation)

The Spring Data REST exporter executes any discovered ResourceProcessor`s before it creates the output representation. It does this by registering a `Converter<Entity, Resource> instance with an internal ConversionService. This is the component responsible for creating the links to referenced entities (e.g. those objects under the _links property in the object’s JSON representation). It takes an @Entity and iterates over its properties, creating links for those properties that are managed by a Repository and copying across any embedded or simple properties.

在它创建输出表示之前,Spring Data REST输出方执行任何发现的资源处理器。它通过注册一个转换器<实体、资源>实例与内部转换服务。这是负责创建引用实体链接的组件(例如那些对象在对象的JSON表示的_links属性下)。它以“实体和遍历它的属性,这些属性创建的存储库和复制在任何嵌入式或简单的物业管理环节。

If your project needs to have output in a different format, however, it’s possible to completely replace the default outgoing JSON representation with your own. If you register your own ConversionService in the ApplicationContext and register your own Converter<Person, Resource>, then you can return a Resource implementation of your choosing.

如果你的项目需要有不同的格式,输出但完全替换你自己的默认输出的JSON表示这是可能的。如果您在应用程序上下文中注册您自己的转换服务,并注册您自己的转换器<人,资源>,那么您可以返回您选择的资源实现。

添加自定义序列化程序Jackson’s 对象映射(Adding custom (de)serializers to Jackson’s ObjectMapper)

Sometimes the behavior of the Spring Data REST’s ObjectMapper, which has been specially configured to use intelligent serializers that can turn domain objects into links and back again, may not handle your domain model correctly. There are so many ways one can structure your data that you may find your own domain model isn’t being translated to JSON correctly. It’s also sometimes not practical in these cases to try and support a complex domain model in a generic way. Sometimes, depending on the complexity, it’s not even possible to offer a generic solution.

有时 Spring Data REST的对象映射数据的行为,已专门配置的使用,可以把域对象链接回来智能系列结果,可能无法正确处理您的域模型。有很多方法可以构造你的数据,你会发现你自己的域模型没有被转化为JSON正确。在这些情况下,它也有时不实际,尝试和支持一个复杂的领域模型在一个通用的方式。有时,根据复杂性,它甚至不可能提供一个通用的解决方案。

So to accommodate the largest percentage of the use cases, Spring Data REST tries very hard to render your object graph correctly. It will try and serialize unmanaged beans as normal POJOs and it will try and create links to managed beans where that’s necessary. But if your domain model doesn’t easily lend itself to reading or writing plain JSON, you may want to configure Jackson’s ObjectMapper with your own custom type mappings and (de)serializers.

因此,以适应使用的情况下,最大百分比的情况下,Spring Data REST试图很难准确地渲染你的对象图。它会尝试序列化托管豆正常POJO和它将尝试创造管理的必要环节,豆子。但是如果你的域模型不容易阅读或写作平原JSON,你可能想与您自己的自定义类型映射配置对象映射和杰克逊的(de)序列化。

抽象类注册(Abstract class registration)

One key configuration point you might need to hook into is when you’re using an abstract class (or an interface) in your domain model. Jackson won’t know by default what implementation to create for an interface. Take the following example:

一个关键的配置点,你可能需要挂钩的是当你使用一个抽象类(或接口)在你的域模型。Jackson将不知道默认是什么实现创建一个接口。采取以下例子:

@Entity
public class MyEntity {

  @OneToMany
  private List<MyInterface> interfaces;
}

In a default configuration, Jackson has no idea what class to instantiate when POSTing new data to the exporter. This is something you’ll need to tell Jackson either through an annotation, or, more cleanly, by registering a type mapping using a Module.

在默认配置中,Jackson不知道类被实例化时,发布新的数据给出口商。这是你需要告诉Jackson的一个注释,或更干净,通过注册一个类型的映射使用一个模块。

Any Module bean declared within the scope of your ApplicationContext will be picked up by the exporter and registered with its ObjectMapper. To add this special abstract class type mapping, create a Module bean and in the setupModule method, add an appropriate TypeResolver:

任何Module`bean声明在你的`ApplicationContext的范围将会被导出并注册到ObjectMapper。加上这特殊的抽象类的类型映射,创建一个Module bean和setupModule的方法,添加一个适当的TypeResolver

public class MyCustomModule extends SimpleModule {

  private MyCustomModule() {
    super("MyCustomModule", new Version(1, 0, 0, "SNAPSHOT"));
  }

  @Override
  public void setupModule(SetupContext context) {
    context.addAbstractTypeResolver(
      new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
        MyInterfaceImpl.class));
  }
}

Once you have access to the SetupContext object in your Module, you can do all sorts of cool things to configure Jackon’s JSON mapping. You can read more about how Module`s work on Jackson’s wiki.

一旦访问ModuleSetupContext对象,你可以做各种很酷的东西来配置Jackon的JSON映射。你可以阅读更多关于模块的http://wiki.fasterxml.com/JacksonFeatureModules[Module`s work on Jackson’s wiki]。

添加域类型的自定义序列化程序(Adding custom serializers for domain types)

If you want to (de)serialize a domain type in a special way, you can register your own implementations with Jackson’s ObjectMapper and the Spring Data REST exporter will transparently handle those domain objects correctly.

如果你想将在这样一个特殊的领域,你可以注册自己的实现到Jackson的ObjectMapper和Spring Data REST的exporter将透明地正确处理这些域对象。

To add serializers, from your setupModule method implementation, do something like the following:

从你的setupModule方法实现添加serializers,像下面这样:

public class MyCustomModule extends SimpleModule {

  …

  @Override
  public void setupModule(SetupContext context) {

    SimpleSerializers serializers = new SimpleSerializers();
    SimpleDeserializers deserializers = new SimpleDeserializers();

    serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
    deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());

    context.addSerializers(serializers);
    context.addDeserializers(deserializers);
  }
}

Now Spring Data REST will correctly handle your domain objects in case they are too complex for the 80% generic use case that Spring Data REST tries to cover.

现在,Spring Data REST将正确处理你的域对象的情况下,他们80%复杂通用的用例Spring Data REST试图覆盖。

Appendix

Appendix A: Using cURL to talk to Spring Data REST

This appendix contains a list of guides that demonstrate interacting with a Spring Data REST service via cURL:

Appendix B: Spring Data REST example projects

This appendix contains a list of Spring Data REST sample applications. The exact version of each example isn’t guaranteed to match the version of this reference manual.

To get them all, visit https://github.com/spring-projects/spring-data-examples and either clone or download a zipball. This will give you example apps for ALL supported Spring Data projects. Simply navigate to spring-data-examples/rest.

Multi-store example

This example shows how to mix together several underlying Spring Data projects.

Projections

This example contains more detailed code you can use to poke around with projections.

Spring Data REST + Spring Security

This example shows how to secure a Spring Data REST application in multiple ways with Spring Security.

Starbucks example

This example exposes 10843 Starbucks coffee shops via a RESTful API that allows to access the stores in a hypermedia based way and exposes a resource to execute geo-location search for coffee shops.