Spring认证中国教育管理中心SpringDataREST框架教程五
原标题:Spring认证中国教育管理中心-Spring Data REST框架教程五(Spring中国教育管理中心)8.3.构建更高效的前端
ETag元素,结合If-Match和If-None-Match标题,让您构建一个对消费者的数据计划和移动电池寿命更友好的前端。这样做: 确定需要锁定的实体并添加版本属性。HTML5 很好地支持data-*属性,因此将版本存储在 DOM 中(例如data-etag属性)。 确定可从跟踪最新更新中受益的条目。获取这些资源时,将Last-Modified值存储在 DOM 中(data-last-modified可能)。 获取资源时,还要self在 DOM 节点中嵌入URI(可能data-uri或data-self),以便轻松返回资源。 调整PUT/ PATCH/DELETE操作中使用If-Match,也处理HTTP412 Precondition Failed状态代码。 调整GET操作以使用If-None-Match和If-Modified-Since处理 HTTP304 Not Modified状态代码。
通过在您的 DOM 中嵌入ETag元素和Last-Modified值(或者对于本机移动应用程序可能在其他地方),您可以通过不一遍又一遍地检索相同的内容来减少数据和电池电量的消耗。您还可以避免与其他客户端发生冲突,而是在需要协调差异时收到警报。
以这种方式,只需对前端进行一些调整和一些实体级别的编辑,后端就会提供对时间敏感的详细信息,您可以在构建客户友好型客户端时从中获利。 9. 验证
Validator在 Spring Data REST 中注册实例有两种方法:通过 bean 名称连接它或手动注册验证器。对于大多数情况,简单的 bean 名称前缀样式就足够了。
为了告诉 Spring Data REST 您希望将Validator特定事件分配给特定事件,请在 bean 名称前加上相关事件。例如,要Person在将新实例保存到存储库之前验证类的实例,您可以Validator在您ApplicationContext的 bean 名称中声明一个 a 的实例beforeCreatePersonValidator。由于beforeCreate前缀与已知的 Spring Data REST 事件匹配,因此该验证器连接到正确的事件。 9.1.手动分配验证器
如果您不想使用 bean 名称前缀方法,则需要向 bean 注册一个验证器实例,该 bean 的工作是在正确的事件之后调用验证器。在您的配置实现RepositoryRestConfigurer,覆盖configureValidatingRepositoryEventListener方法并调用addValidator上ValidatingRepositoryEventListener,传递要触发这个验证程序和验证的一个实例。以下示例显示了如何执行此操作: @Override void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) { v.addValidator("beforeSave", new BeforeSaveValidator()); }10. 活动
REST 导出器在使用实体的整个过程中发出八种不同的事件: BeforeCreateEvent AfterCreateEvent BeforeSaveEvent AfterSaveEvent BeforeLinkSaveEvent AfterLinkSaveEvent BeforeDeleteEvent AfterDeleteEvent 10.1.写一个ApplicationListener
您可以创建一个抽象类的子类,该类侦听这些类型的事件并根据事件类型调用适当的方法。为此,请覆盖相关事件的方法,如下所示: 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 } }
但是,这种方法需要注意的一点是,它不会根据实体的类型进行区分。你必须自己检查。10.2.编写带注释的处理程序
另一种方法是使用带注释的处理程序,它根据域类型过滤事件。
要声明处理程序,请创建一个 POJO 并@RepositoryEventHandler在其上放置注释。这告诉BeanPostProcessor该类需要检查处理程序方法。
一旦BeanPostProcessor找到带有此注释的 bean,它就会遍历公开的方法并查找与相关事件对应的注释。例如,要处理BeforeSaveEvent不同类型域类型的带注释的 POJO 中的实例,您可以按如下方式定义您的类:@RepositoryEventHandler 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 } }
可以通过使用 (例如) 来缩小此处理程序适用的类型@RepositoryEventHandler(Person.class)。
您感兴趣的事件的域类型由注释方法的第一个参数的类型确定。
要注册您的事件处理程序,请使用 Spring 的@Component构造型之一标记该类(以便它可以被@SpringBootApplication或选取@ComponentScan)或在您的ApplicationContext. 然后在BeanPostProcessor中创建的RepositoryRestMvcConfiguration检查 bean 的处理程序并将它们连接到正确的事件。以下示例显示了如何为类创建事件处理程序Person: @Configuration public class RepositoryConfiguration { @Bean PersonEventHandler personEventHandler() { return new PersonEventHandler(); } }
Spring Data REST 事件是定制的Spring 应用程序事件。默认情况下,Spring 事件是同步的,除非它们跨边界重新发布(例如发出 WebSocket 事件或跨入线程)。11. 整合
本节详细介绍了与 Spring Data REST 组件集成的各种方法,无论是从使用 Spring Data REST 的 Spring 应用程序还是通过其他方式。 11.1.程序链接
有时您需要在自己定制的 Spring MVC 控制器中添加指向导出资源的链接。共有三个基本级别的链接可用: 手动组装链接。 将 Spring HATEOAS LinkBuilder 与linkTo()、slash()等一起使用。使用 Spring Data REST 的 RepositoryEntityLinks .
第一个建议很糟糕,应该不惜一切代价避免。它使您的代码脆弱且风险高。第二个在创建到其他手写 Spring MVC 控制器的链接时很方便。最后一个,我们将在本节的其余部分探讨,适用于查找 Spring Data REST 导出的资源链接。
考虑以下使用 Spring 自动装配的类: public class MyWebApp { private RepositoryEntityLinks entityLinks; @Autowired public MyWebApp(RepositoryEntityLinks entityLinks) { this.entityLinks = entityLinks; } }
对于前面示例中的类,您可以使用以下操作:
所有基于搜索的链接都支持用于分页和排序的额外参数。详情请参阅RepositoryEntityLinks。还有linkFor(Class<?> type),但它会返回一个 Spring HATEOAS LinkBuilder,它会将您返回到较低级别的 API。先尝试使用其他的。12. 元数据
本节详细介绍 Spring Data 基于 REST 的应用程序提供的各种形式的元数据。 12.1.应用程序级配置文件语义 (ALPS)
ALPS是一种数据格式,用于定义应用程序级语义的简单描述,其复杂性类似于 HTML 微格式。一个 ALPS 文档可以作为一个配置文件来解释具有与应用程序无关的媒体类型(例如 HTML、HAL、Collection+JSON、Siren 等)的文档的应用程序语义。这增加了跨媒体类型的配置文件的可重用性。
— M. Admundsen / L. Richardson / M. Fosterhttps://tools.ietf.org/html/draft-amundsen-richardson-foster-alps-00
Spring Data REST 为每个导出的存储库提供一个 ALPS 文档。它包含有关 RESTful 转换和每个存储库的属性的信息。
Spring Data REST 应用程序的根是一个配置文件链接。假设您有一个同时包含persons和 related的应用程序addresses,根文档将如下所示: { "_links" : { "persons" : { "href" : "http://localhost:8080/persons" }, "addresses" : { "href" : "http://localhost:8080/addresses" }, "profile" : { "href" : "http://localhost:8080/profile" } } }
RFC 6906 中定义的配置文件链接是包含应用程序级详细信息的地方。该 ALPS规范草案旨在定义特定配置文件格式,这是我们在本节后面探索。
如果您导航到 的个人资料链接localhost:8080/profile,您会看到类似于以下内容的内容:{ "_links" : { "self" : { "href" : "http://localhost:8080/profile" }, "persons" : { "href" : "http://localhost:8080/profile/persons" }, "addresses" : { "href" : "http://localhost:8080/profile/addresses" } } }
在根级别,profile是一个链接,不能提供多个应用程序配置文件。这就是为什么您必须导航以/profile找到每个资源元数据的链接。
如果您导航/profile/persons并查看Person资源的配置文件数据,您会看到类似于以下示例的内容: { "version" : "1.0", "descriptors" : [ { "id" : "person-representation", "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", "name" : "persons", "type" : "UNSAFE", "rt" : "#person-representation" }, { "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" } ] }
此 JSON 文档的媒体类型为application/alps+json. 这与之前的 JSON 文档不同,后者的媒体类型为application/hal+json. 这些格式是不同的,并由不同的规范管理。
您还可以profile在_links检查集合资源时在集合中找到链接,如下例所示: { "_links" : { "self" : { "href" : "http://localhost:8080/persons" }, ... other links ... "profile" : { "href" : "http://localhost:8080/profile/persons" } }, ... }
此 HAL 文档代表了Person集合。
它有一个指向元数据相同 URI的配置文件链接。
同样,默认情况下,该profile链接提供 ALPS。但是,如果您使用Acceptheader,它可以提供application/alps+json.