本书接文???WhatmakessomethingRESTful?到目前为止,您已经有了一个基于Web的服务来处理涉及员工数据的核心操作。但这还不足以让事情变得“RESTful”。漂亮的URL/employees/3不是REST。仅使用GET、POST等不是REST。安排所有针对REST的CRUD操作。事实上,到目前为止我们所构建的最好描述为RPC(远程过程调用)。那是因为无法知道如何与该服务器进行交互。如果您今天发布它,您还必须编写文档或在某个地方托管开发人员门户,其中包含所有详细信息。RoyFielding的这句话可能进一步阐明了REST和RPC之间的区别:我对将任何基于HTTP的接口称为RESTAPI的人数感到沮丧。今天的示例是SocialSiteRESTAPI。那就是RPC。它尖叫着RPC。表现出过多的耦合,值得X评级。可以做些什么来清楚地认识到超文本是使用REST架构风格的约束?换句话说,如果应用程序状态引擎(以及API)不是超文本驱动的,那么它就不能是RESTful,也不能是RESTAPI。时期。是否有一些损坏的手册需要修复?–RoyFieldinghttps://roy.gbiv.com/untangle...在我们的表示中不包含超媒体的副作用是客户必须对URI进行硬编码才能导航API。这导致了与在线电子商务兴起之前相同的漏洞。这表明我们的JSON输出需要一点帮助。介绍SpringHATEOAS,这是一个旨在帮助您创作超媒体驱动输出的Spring项目。要将您的服务升级为RESTful,请将其添加到您的构建中:将SpringHATEOAS依赖项添加到pom.xmlorg.springframework.bootspring-boot-starter-hateoas复制这个小库将为我们提供定义RESTful服务的结构,然后以可接受的格式呈现它以供客户端使用。任何RESTful服务的一个关键要素是添加指向相关操作的链接。为了使您的控制器更加RESTful,添加这样的链接:)//.orElseThrow(()->newEmployeeNotFoundException(id));returnEntityModel.of(employee,//linkTo(methodOn(EmployeeController.class).one(id)).withSelfRel(),linkTo(methodOn(EmployeeController.class).all()).withRel("employees"));本教程基于SpringMVC并使用静态帮助器方法WebMvcLinkBuilder来构建这些链接。如果您在项目中使用SpringWebFlux,则必须改用WebFluxLinkBuilder。这与我们之前的非常相似,但有一些变化:方法的返回类型已从Employee更改为EntityModel。EntityModel是来自SpringHATEOAS的通用容器,它不仅包含数据,还包含链接集合。linkTo(methodOn(EmployeeController.class).one(id)).withSelfRel()要求SpringHATEOAS建立到EmployeeController的one()方法的链接并将其标记为自链接。linkTo(methodOn(EmployeeController.class).all()).withRel("employees")要求SpringHATEOAS建立到聚合根all()的链接并将其称为“employees”。“建立链接”是什么意思?SpringHATEOAS的核心类型之一是Link。它包括一个URI和一个rel(关系)。链接是赋予网络力量的东西。在万维网之前,其他文档系统提供信息或链接,但它是将文档与这种将Web缝合在一起的关系元数据链接在一起。RoyFielding鼓励使用使网络成功的相同技术来构建API,链接就是其中之一。如果您重新启动应用程序并查询Bilbo的员工记录,您会得到与之前略有不同的响应:Curlingisprettier。随着您的curl输出变得越来越复杂,它会变得难以阅读。使用这个或其他技巧来美化curl返回的json:#指令部分将输出通过管道传输到json_pp并要求它美化您的JSON。(或者使用任何你喜欢的工具!)#v----------------vcurl-vlocalhost:8080/employees/1|json_pp单个员工的RESTful表示{"id":1,"name":"BilboBaggins","role":"burglar","_links":{"self":{"href":"http://localhost:8080/employees/1"},"employees":{"href":"http://localhost:8080/employees"}}}这个解压后的输出不仅展示了你看到的角色的数据元素(id和name)更早,而且_links包含两个URI的条目。整个文档使用HAL进行格式化。HAL是一种轻量级媒体类型,它不仅对数据进行编码,而且对超媒体控件进行编码,提醒消费者注意他们可以导航的API的其他部分。在这种情况下,有一个“自我”链接(有点像代码中的这个语句)和一个返回聚合根的链接。为了使聚合根也更加RESTful,您希望包括顶级链接,以及其中的任何RESTful组件。所以我们把这个getaggregateroot@GetMapping("/employees")Listall(){returnrepository.findAll();}放到这个getaggregateroot@GetMapping("/employees")CollectionModel>all(){List>employees=repository.findAll().stream().map(employee->EntityModel.of(employee,linkTo(methodOn(EmployeeController.class).one(employee.getId())).withSelfRel(),linkTo(methodOn(EmployeeController.class).all()).withRel("employees"))).collect(Collectors.toList());返回CollectionModel.of(employees,linkTo(methodOn(EmployeeController.class).all()).withSelfRel());}哇!旧方法repository.findAll()已经长大了!不用担心。让我们打开它。CollectionModel<>是另一个SpringHATEOAS容器;它旨在封装资源集合,而不是像EntityModel<>以前所做的那样封装单个资源实体。CollectionModel<>,它还允许您包含链接。不要让第一个陈述溜走。“封装一个集合”是什么意思?员工最爱?不完全的。既然我们在谈论REST,它应该封装员工资源的集合。这就是为什么您获取所有员工,然后将它们转换为EntityModel对象列表的原因。(感谢Java8流!)如果您重新启动应用程序并获取聚合根,您可以看到它现在的样子。员工资源集合的RESTful表示{"_embedded":{"employeeList":[{"id":1,"name":"BilboBaggins","role":"burglar","_links":{"self":{"href":"http://localhost:8080/employees/1"},"employees":{"href":"http://localhost:8080/employees"}}},{"id":2,"name":"FrodoBaggins","role":"thief","_links":{"self":{"href":"http://localhost:8080/employees/2"},"employees":{"href":"http://localhost:8080/employees"}}}]},"_links":{"self":{"href":"http://localhost:8080/employees"}}对于提供员工资源集合的聚合根,有一个顶级“自我”链接。“集合”列在“_embedded”部分下;这就是HAL表示集合的方式。集合中的每个成员都有自己的信息和相关链接。添加所有这些链接有什么意义?它使得随着时间的推移发展REST服务成为可能。可以维护现有链接,同时可以在将来添加新链接。新客户可以利用新链接,而老客户可以依靠旧链接维持生计。如果重新定位和移动服务,这尤其有用。只要保持链接结构,客户仍然可以找到事物并与之交互。简化链接创建在前面的代码中,您是否注意到个别员工链接创建中的重复?提供指向员工的单一链接和创建指向聚合根的“员工”链接的代码显示了两次。如果这引起了您的注意,那就太好了!有一个解决方案。简单地说,您需要定义一个函数,将Employee对象转换为EntityModel对象。虽然您自己可以轻松编写此代码,但在实现SpringHATEOAS的RepresentationModelAssembler接口的过程中会有一些好处——它将为您完成这项工作。evolve/src/main/java/payroll/EmployeeModelAssembler.javapackagepayroll;导入静态org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*;导入org.springframework.hateoas.EntityModel;导入org.springframework.hateoas.server.RepresentationModelAssembler;importorg.springframework.stereotype.Component;@ComponentclassEmployeeModelAssemblerimplementsRepresentationModelAssembler>{@OverridepublicEntityModeltoModel(Employeeemployee){返回EntityModel.of(employee,//OnlinkTo(methodEmployeeController.class).one(employee.getId())).withSelfRel(),linkTo(methodOn(EmployeeController.class).all()).withRel("employees"));这个简单的接口有一个方法:toModel()。它基于将非模型对象(Employee)转换为基于模型的对象(EntityModel)。您之前在控制器中看到的所有代码都可以移到此类中。并且通过应用SpringFramework的@Component注释,汇编器将在应用程序启动时自动创建。SpringHATEOAS中所有模型的抽象基类是RepresentationModel。但为简单起见,我建议使用EntityModel作为您的机制,以轻松地将所有POJO包装为模型。要利用此汇编程序,您只需通过在构造函数中注入汇编程序来更改EmployeeController。将EmployeeModelAssembler注入控制器@RestControllerclassEmployeeController{privatefinalEmployeeRepositoryrepository;私有最终EmployeeModelAssembler汇编程序;EmployeeController(EmployeeRepositoryrepository,EmployeeModelAssemblerassembler){你可以从这里得到this.repository},assembler=this.在单个员工方法中使用此汇编程序:使用汇编程序获取单个资源@GetMapping("/employees/{id}")EntityModelone(@PathVariableLongid){Employeeemployee=repository.findById(id)//.orElseThrow(()->newEmployeeNotFoundException(id));returnassembler.toModel(employee);}这段代码几乎是一样的,除了这里没有创建EntityModel的实例,而是将它委托给汇编器设备。也许这看起来并不多。在聚合根控制器方法中应用相同的东西更令人印象深刻:使用汇编程序获取聚合根资源@GetMapping("/employees")CollectionModel>all(){List>employees=repository.findAll().stream()//.map(assembler::toModel)//.collect(Collectors.toList());returnCollectionModel.of(employees,linkTo(methodOn(EmployeeController.class).all()).withSelfRel());}同样,代码几乎相同,但是您可以用map(汇编程序::toModel)。借助Java8方法引用设备,插入它并简化您的控制非常容易。SpringHATEOAS的一个关键设计目标是让TheRightThing?变得更容易。在这种情况下:将超媒体添加到您的服务中而无需硬编码。在此阶段,您已经创建了一个实际生成超媒体驱动内容的SpringMVCREST控制器!不使用HAL的客户端在使用普通数据时可以忽略额外的位。使用HAL的客户端可以浏览您授权的API。但这并不是使用Spring构建真正的RESTful服务所需的唯一东西。......未完待续...#java##springcertification##springcertification##programmer#2022就业季|SpringCertification教你如何使用Spring搭建REST服务2022就业季|SpringCertification教你如何使用Spring搭建REST服务(二)以上就是今天关于Spring的一些讨论。对你有帮助吗?如果您有兴趣了解更多,欢迎在春天中国教育管理中心留言!