spring rest data序列化为一个关联作为相关实体

时间:2017-02-17 23:03:54

标签: java spring rest hateoas

如何配置Spring Data Rest直接序列化相关实体

我希望它看起来像这样:请注意“所有者”链接是指“帐户”实体。

{
  "name" : "customer",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/api/v1/servers/1005"
    },
    "owner" : {
      "href" : "http://localhost:8081/api/v1/account/100"
    }
  }
}

目前(默认)具有间接序列化的相关实体(也称为关联)。

我不希望它看起来像这样:“所有者”链接是通过自助服务器实体。

{
  "name" : "customer",
  "_links" : {
    "self" : {
      "href" : "http://localhost:8081/api/v1/servers/1005"
    },
    "owner" : {
      "href" : "http://localhost:8081/api/v1/servers/1005/owner"
    }
  }
}

我检查了文档,但没有找到任何提及“直接”路线。

1 个答案:

答案 0 :(得分:1)

解决了hackage。

步骤:

  1. @RestResource(exported = false)添加到实体上的关联。
  2. 注册ResourceProcessor<Resource<OwnedEntity>> @Bean(OwnedEntity是我拥有所有者的实体的基类)并更改该方法中的链接集合。
  3. 详细信息位于Customizing the JSON output section of the Spring Data REST reference docs

    按要求,这里有一些代码可以执行此操作:

    /*
     * Copyright (c) 2017. DataVolo, Inc.  All Rights Reserved.
     */
    
    package com.datavolo.tenant.web;
    
    import com.datavolo.tenant.domain.Account;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks;
    import org.springframework.hateoas.Link;
    import org.springframework.hateoas.mvc.ResourceAssemblerSupport;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Nonnull;
    
    /**
     *
     */
    @Component
    public class AccountResourceAssembler extends ResourceAssemblerSupport<Account, AccountResource> {
    
        private final RepositoryEntityLinks repositoryEntityLinks;
    
        @Autowired
        public AccountResourceAssembler(@Nonnull RepositoryEntityLinks repositoryEntityLinks) {
            super(AccountController.class, AccountResource.class);
            this.repositoryEntityLinks = repositoryEntityLinks;
        }
    
        @Override
        public AccountResource toResource(Account entity) {
            Link accountLink = repositoryEntityLinks.linkToSingleResource(Account.class, entity.getId());
            String accountHref = accountLink.getHref();
            Link selfLink = new Link(accountHref, Link.REL_SELF);
    
            Link subAccounts = new Link(accountHref + "/subAccounts", "subAccounts");
            Link owner = new Link(accountHref + "/owner", "owner");
    
            Account parent = entity.getParent();
            Link[] links;
            if (parent == null) {
                links = new Link[] {selfLink, accountLink, subAccounts, owner};
            } else {
                Link parentAccountLink = repositoryEntityLinks.linkToSingleResource(Account.class, parent.getId());
                Link parentLink = new Link(parentAccountLink.getHref(), "parent");
                links = new Link[] {selfLink, accountLink, subAccounts, owner, parentLink};
            }
    
            return new AccountResource(entity, links);
        }
    }
    

    然后将其注入控制器(注释为@RepositoryRestController),然后生成响应。

    在这个系统中,我们有一个控制器的共享基类,我们有一个多租户设置,其中所有非平凡的非查找域对象(例如,存储系统数据的所有内容)都参考直接或间接的帐户对象,这是控制和代表租赁。因此,我们在一个地方为一个对象执行此操作,我们已完成。其他链接更加手动,随着时间的推移,我们大部分只是耸耸肩,并保持默认的Spring HATEOS输出,并让客户调整它。我们只有在默认情况下经常导致后端多次往返时才改变它 - 这是Spring处理它的默认方式的基本问题。但这是一个权衡。当后端资源本身被声明为延迟解析引用时,Spring的默认值意味着不会产生额外的开销。对它的一个很好的改进是让它更聪明地使用那些资源,以便已经获取的资源在REST响应中由它们自己的id直接引用。