javascript
使用JAX-RS和Spring构建HATEOAS API
在我以前的博客文章中,我展示了如何使用Spring Boot配置Jersey多么容易。 我對Spring Boot和Jersey的探索并沒有結束,我研究了在Spring Boot應用程序中將Spring HATEOAS和Jersey一起使用的可能性。 Spring HATEOS允許創建遵循HATEOAS原理的REST表示形式,并且(截至撰寫本文時)具有使用鏈接的基本JAX-RS支持。 在這篇博客中,我將分享一些示例,說明如何將Spring HATEOAS與Jersey集成到Spring Boot應用程序中。
介紹
作為本文的基礎,我使用了之前創建的示例:( https://github.com/kolorobot/spring-boot-jersey-demo )。
為了開始使用Spring HATEOAS,我在build.gradle中添加了有效的依賴build.gradle :
compile("org.springframework.hateoas:spring-hateoas:0.16.0.RELEASE")使用
生成實體對象( Customer )表示的最快方法是使用Spring HATEOAS Resource和Resources助手。 后者包裝了CustomerRepository返回的實體的集合。 為了生成鏈接,我使用了JaxRsLinkBuilder ,它通過基于@Path注釋發現路徑來幫助構建到JAX-RS資源的資源鏈接。
@Component @Path("/customer") @Produces(MediaType.APPLICATION_JSON) public class CustomerController {@Injectprivate CustomerRepository customerRepository;@GETpublic Response findAll() {Resources<Customer> resources = new Resources<>(customerRepository.findAll(),JaxRsLinkBuilder.linkTo(CustomerController.class).withSelfRel());return Response.ok(resources).build();}調用上述方法的結果將是帶有自相關鏈接的收集資源:
{"links": [{"rel": "self","href": "http://localhost:8080/customer"}],"content": [{"id": 1,"firstname": "Dave","lastname": "Matthews","emailAddress": {"value": "dave@dmband.com"}}] }使用
Resource , Resources , PagedResources幫助器非常方便,但是在某些情況下,需要對創建的資源進行更多控制。
要從實體創建自定義傳輸對象,可以使用ResourceSupport基類:
public class CustomerResource extends ResourceSupport {private String fullName;private String email;}要從實體組裝CustomerResource并自動向其添加自相關鏈接,應使用ResourceAssemblerSupport類。 基本上,此類負責實例化資源并添加具有rel自指向該資源的鏈接:
public class CustomerResourceAssembler extends ResourceAssemblerSupport<Customer, CustomerResource> {public CustomerResourceAssembler() {super(CustomerController.class, CustomerResource.class);}@Overridepublic CustomerResource toResource(Customer entity) {CustomerResource resource = createResourceWithId(entity.getId(),entity);// initialize the resource return resource;} }我在上面的代碼中遇到的問題是ResourceAssemblerSupport類在內部使用鏈接構建器來構建到Spring MVC控制器( ControllerLinkBuilder )的鏈接。 這導致鏈接無效。
除了創建從ResourceAssemblerSupport擴展并覆蓋其父級行為的新支持類外,我沒有發現其他方法:
public abstract class JaxRsResourceAssemblerSupport<T, D extends ResourceSupport>extends ResourceAssemblerSupport<T, D> {private final Class<?> controllerClass;public JaxRsResourceAssemblerSupport(Class<?> controllerClass, Class<D> resourceType) {super(controllerClass, resourceType);this.controllerClass = controllerClass;}@Overrideprotected D createResourceWithId(Object id, T entity, Object... parameters) {Assert.notNull(entity);Assert.notNull(id);D instance = instantiateResource(entity);instance.add(JaxRsLinkBuilder.linkTo(controllerClass, parameters).slash(id).withSelfRel());return instance;} }我真的不喜歡上面的解決方案,因為我需要復制和粘貼一些代碼,但是我沒有找到實現我想要的更好的方法。
我的匯編器現在從新創建的JaxRsResourceAssemblerSupport :
public class CustomerResourceAssembler extends JaxRsResourceAssemblerSupport<Customer, CustomerResource> {}最后,我可以修改控制器的方法以返回由我的匯編器匯編的資源。 請注意, ResourceAssemblerSupport提供了方便的方法來將所有給定的實體轉換為資源:
@GET @Path("/resources") public Response findAll() {Iterable<Customer> customers = customerRepository.findAll();CustomerResourceAssembler assembler = new CustomerResourceAssembler();List<CustomerResource> resources = assembler.toResources(customers);return Response.ok(wrapped).build(); }要添加具有自相關鏈接的集合資源鏈接,我需要使用前面提到的Resources類包裝它:
// wrap to add link Resources<CustomerResource> wrapped = new Resources<>(resources); wrapped.add(JaxRsLinkBuilder.linkTo(CustomerController.class).withSelfRel() );現在返回的表示看起來更像是HATEOAS:
{"links": [{"rel": "self","href": "http://localhost:8080/customer"}],"content": [{"fullName": "Matthews, Dave","email": "dave@dmband.com","links": [{"rel": "self","href": "http://localhost:8080/customer/1"}]}] }使用
EntityLinks接口提供API以根據實體類型創建鏈接,并且@EnableEntityLinks或@EnableHypermadiaSupport與@ExposesResourceFor一起使用時,可用于依賴項注入。 @ExposesResourceFor公開Spring MVC控制器或JAX-RS資源管理的實體類型。
在配置類中,我們需要激活實體鏈接:
@SpringBootApplication @EnableEntityLinks public class Application {}注意:請注意,使用實體鏈接和@EnableEntityLinks ,以下依賴項必須位于類路徑上:
compile("org.springframework.plugin:spring-plugin-core:1.1.0.RELEASE")任何支持實體類型的JAX-RS資源都必須使用@ExposesResourceFor進行標記,以便可以注入EntityLinks :
@ExposesResourceFor(Customer.class) public class CustomerController {@Injectprivate EntityLinks entityLinks; }基本上, EntityLinks接口提供了返回鏈接到集合資源或單個資源的方法。 例:
Link selfRel = entityLinks.linkToSingleResource(Customer.class, customer.getId() ).withSelfRel();摘要
Spring HATEOAS不是使用JAX-RS和Jersey構建HATEOAS API的唯一選擇,但是有可能在Spring Boot應用程序中使用Jersey,Spring HATEOAS可能是不錯的補充,尤其是考慮到JAX-RS的設計。
注意:本文只是我針對所述主題進行的一項研究。 我尚未在任何項目中使用該方法。
資源資源
- 項目源代碼: https : //github.com/kolorobot/spring-boot-jersey-demo
- SpringHATEOAS項目頁面: https : //github.com/spring-projects/spring-hateoas和示例: https : //github.com/olivergierke/spring-hateoas-sample
翻譯自: https://www.javacodegeeks.com/2015/01/building-a-hateoas-api-with-jax-rs-and-spring.html
總結
以上是生活随笔為你收集整理的使用JAX-RS和Spring构建HATEOAS API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux c 库文件(linux c
- 下一篇: 备案价就是开盘价吗为什么(备案价就是开盘