原标题:Spring认证中国教育管理中心SpringDataREST框架教程五(Spring中国教育管理中心)8。3。构建更高效的前端 ETag元素,结合IfMatch和IfNoneMatch标题,让您构建一个对消费者的数据计划和移动电池寿命更友好的前端。这样做:确定需要锁定的实体并添加版本属性。HTML5很好地支持data属性,因此将版本存储在DOM中(例如dataetag属性)。确定可从跟踪最新更新中受益的条目。获取这些资源时,将LastModified值存储在DOM中(datalastmodified可能)。获取资源时,还要self在DOM节点中嵌入URI(可能datauri或dataself),以便轻松返回资源。调整PUTPATCHDELETE操作中使用IfMatch,也处理HTTP412PreconditionFailed状态代码。调整GET操作以使用IfNoneMatch和IfModifiedSince处理HTTP304NotModified状态代码。 通过在您的DOM中嵌入ETag元素和LastModified值(或者对于本机移动应用程序可能在其他地方),您可以通过不一遍又一遍地检索相同的内容来减少数据和电池电量的消耗。您还可以避免与其他客户端发生冲突,而是在需要协调差异时收到警报。 以这种方式,只需对前端进行一些调整和一些实体级别的编辑,后端就会提供对时间敏感的详细信息,您可以在构建客户友好型客户端时从中获利。9。验证 Validator在SpringDataREST中注册实例有两种方法:通过bean名称连接它或手动注册验证器。对于大多数情况,简单的bean名称前缀样式就足够了。 为了告诉SpringDataREST您希望将Validator特定事件分配给特定事件,请在bean名称前加上相关事件。例如,要Person在将新实例保存到存储库之前验证类的实例,您可以Validator在您ApplicationContext的bean名称中声明一个a的实例beforeCreatePersonValidator。由于beforeCreate前缀与已知的SpringDataREST事件匹配,因此该验证器连接到正确的事件。9。1。手动分配验证器 如果您不想使用bean名称前缀方法,则需要向bean注册一个验证器实例,该bean的工作是在正确的事件之后调用验证器。在您的配置实现RepositoryRestConfigurer,覆盖configureValidatingRepositoryEventListener方法并调用addValidator上ValidatingRepositoryEventListener,传递要触发这个验证程序和验证的一个实例。以下示例显示了如何执行此操作:OverridevoidconfigureValidatingRepositoryEventListener(ValidatingRepositoryEventListenerv){v。addValidator(beforeSave,newBeforeSaveValidator());}10。活动 REST导出器在使用实体的整个过程中发出八种不同的事件:BeforeCreateEventAfterCreateEventBeforeSaveEventAfterSaveEventBeforeLinkSaveEventAfterLinkSaveEventBeforeDeleteEventAfterDeleteEvent10。1。写一个ApplicationListener 您可以创建一个抽象类的子类,该类侦听这些类型的事件并根据事件类型调用适当的方法。为此,请覆盖相关事件的方法,如下所示:publicclassBeforeSaveEventListenerextendsAbstractRepositoryEventListener{OverridepublicvoidonBeforeSave(Objectentity){。。。logictohandleinspectingtheentitybeforetheRepositorysavesit}OverridepublicvoidonAfterDelete(Objectentity){。。。sendamessagethatthisentityhasbeendeleted}} 但是,这种方法需要注意的一点是,它不会根据实体的类型进行区分。你必须自己检查。10。2。编写带注释的处理程序 另一种方法是使用带注释的处理程序,它根据域类型过滤事件。 要声明处理程序,请创建一个POJO并RepositoryEventHandler在其上放置注释。这告诉BeanPostProcessor该类需要检查处理程序方法。 一旦BeanPostProcessor找到带有此注释的bean,它就会遍历公开的方法并查找与相关事件对应的注释。例如,要处理BeforeSaveEvent不同类型域类型的带注释的POJO中的实例,您可以按如下方式定义您的类:RepositoryEventHandlerpublicclassPersonEventHandler{HandleBeforeSavepublicvoidhandlePersonSave(Personp){youcannowdealwithPersoninatypesafeway}HandleBeforeSavepublicvoidhandleProfileSave(Profilep){youcannowdealwithProfileinatypesafeway}} 可以通过使用(例如)来缩小此处理程序适用的类型RepositoryEventHandler(Person。class)。 您感兴趣的事件的域类型由注释方法的第一个参数的类型确定。 要注册您的事件处理程序,请使用Spring的Component构造型之一标记该类(以便它可以被SpringBootApplication或选取ComponentScan)或在您的ApplicationContext。然后在BeanPostProcessor中创建的RepositoryRestMvcConfiguration检查bean的处理程序并将它们连接到正确的事件。以下示例显示了如何为类创建事件处理程序Person:ConfigurationpublicclassRepositoryConfiguration{BeanPersonEventHandlerpersonEventHandler(){returnnewPersonEventHandler();}} SpringDataREST事件是定制的Spring应用程序事件。默认情况下,Spring事件是同步的,除非它们跨边界重新发布(例如发出WebSocket事件或跨入线程)。11。整合 本节详细介绍了与SpringDataREST组件集成的各种方法,无论是从使用SpringDataREST的Spring应用程序还是通过其他方式。11。1。程序链接 有时您需要在自己定制的SpringMVC控制器中添加指向导出资源的链接。共有三个基本级别的链接可用:手动组装链接。将SpringHATEOASLinkBuilder与linkTo()、slash()等一起使用。使用SpringDataREST的RepositoryEntityLinks。 第一个建议很糟糕,应该不惜一切代价避免。它使您的代码脆弱且风险高。第二个在创建到其他手写SpringMVC控制器的链接时很方便。最后一个,我们将在本节的其余部分探讨,适用于查找SpringDataREST导出的资源链接。 考虑以下使用Spring自动装配的类:publicclassMyWebApp{privateRepositoryEntityLinksentityLAutowiredpublicMyWebApp(RepositoryEntityLinksentityLinks){this。entityLinksentityL}} 对于前面示例中的类,您可以使用以下操作: 所有基于搜索的链接都支持用于分页和排序的额外参数。详情请参阅RepositoryEntityLinks。还有linkFor(C?type),但它会返回一个SpringHATEOASLinkBuilder,它会将您返回到较低级别的API。先尝试使用其他的。12。元数据 本节详细介绍SpringData基于REST的应用程序提供的各种形式的元数据。12。1。应用程序级配置文件语义(ALPS) ALPS是一种数据格式,用于定义应用程序级语义的简单描述,其复杂性类似于HTML微格式。一个ALPS文档可以作为一个配置文件来解释具有与应用程序无关的媒体类型(例如HTML、HAL、CollectionJSON、Siren等)的文档的应用程序语义。这增加了跨媒体类型的配置文件的可重用性。 M。AdmundsenL。RichardsonM。Fosterhttps:tools。ietf。orghtmldraftamundsenrichardsonfosteralps00 SpringDataREST为每个导出的存储库提供一个ALPS文档。它包含有关RESTful转换和每个存储库的属性的信息。 SpringDataREST应用程序的根是一个配置文件链接。假设您有一个同时包含persons和related的应用程序addresses,根文档将如下所示:{links:{persons:{href:http:localhost:8080persons},addresses:{href:http:localhost:8080addresses},profile:{href:http:localhost:8080profile}}} RFC6906中定义的配置文件链接是包含应用程序级详细信息的地方。该ALPS规范草案旨在定义特定配置文件格式,这是我们在本节后面探索。 如果您导航到的个人资料链接localhost:8080profile,您会看到类似于以下内容的内容:{links:{self:{href:http:localhost:8080profile},persons:{href:http:localhost:8080profilepersons},addresses:{href:http:localhost:8080profileaddresses}}} 在根级别,profile是一个链接,不能提供多个应用程序配置文件。这就是为什么您必须导航以profile找到每个资源元数据的链接。 如果您导航profilepersons并查看Person资源的配置文件数据,您会看到类似于以下示例的内容:{version:1。0,descriptors:〔{id:personrepresentation,descriptors:〔{name:firstName,type:SEMANTIC},{name:lastName,type:SEMANTIC},{name:id,type:SEMANTIC},{name:address,type:SAFE,rt:http:localhost:8080profileaddressesaddress}〕},{id:createpersons,name:persons,type:UNSAFE,rt:personrepresentation},{id:getpersons,name:persons,type:SAFE,rt:personrepresentation},{id:deleteperson,name:person,type:IDEMPOTENT,rt:personrepresentation},{id:patchperson,name:person,type:UNSAFE,rt:personrepresentation},{id:updateperson,name:person,type:IDEMPOTENT,rt:personrepresentation},{id:getperson,name:person,type:SAFE,rt:personrepresentation}〕} 此JSON文档的媒体类型为applicationalpsjson。这与之前的JSON文档不同,后者的媒体类型为applicationhaljson。这些格式是不同的,并由不同的规范管理。 您还可以profile在links检查集合资源时在集合中找到链接,如下例所示:{links:{self:{href:http:localhost:8080persons},。。。otherlinks。。。profile:{href:http:localhost:8080profilepersons}},。。。} 此HAL文档代表了Person集合。 它有一个指向元数据相同URI的配置文件链接。 同样,默认情况下,该profile链接提供ALPS。但是,如果您使用Acceptheader,它可以提供applicationalpsjson。