spring rest data序列化为一个关联作为相关实体 [英] spring rest data serialize to-one associations as related entity

查看:187
本文介绍了spring rest data序列化为一个关联作为相关实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How does one configure Spring Data Rest to serialize related entities directly?

我希望它看起来像这样: / strong>请注意所有者链接指向帐户实体。

I want it to look like this: note the "owner" link is to an "account" entity.

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

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

Currently (the default) has related entities (aka, associations) serialized indirectly.

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

I DON'T want it to look like this: the "owner" link is via the self server entity.

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

我检查过文档但不能找到任何关于直接路线的提及。

I've checked the docs and can't find any mention of going the "direct" route.

推荐答案

解决了hackage。

Solved with hackage.

步骤:


  1. 添加 @RestResource(exported = false)到实体的关联。

  2. 注册 ResourceProcessor<资源< OwnedEntity>> @Bean (OwnedEntity是我拥有所有者的实体的基类)并更改该方法中的链接集合。

  1. Add the @RestResource(exported = false) to the association on the entity.
  2. Register a ResourceProcessor<Resource<OwnedEntity>> @Bean (OwnedEntity is my base class for entities that have an owner) and change the collection of links in that method.

详情见自定义Spring Data REST参考文档的JSON输出部分

按请求,这里有一些代码可以执行这个:

By Request, here's some code that does this:

/*
 * 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 )反过来生成响应。

That then gets injected into the Controllers (annotated with @RepositoryRestController) that, in turn, generate the response.

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

In this system we have a shared base class for the controllers, and we have a multi-tenant setup where all non-trivial, non-lookup domain objects (e.g., everything that's storing system data) reference either directly or indirectly the account object, which is what controls and represents the tenancy. So we do this in one place for one object and we're done. Other links are more manual and over time we've largely just shrugged and left the default Spring HATEOS output as-is and let the clients adjust to it. We change this only when the default routinely causes multiple round-trips to the backend -- which is the essential problem with that default way Spring has of handling it. But it's a tradeoff. Spring's default is meant to cause no extra overhead when the back-end resource itself is declared as lazily resolved reference. The nice enhancement to that would be to have it be smarter about those resources so that ones that are already fetched are directly referenced by their own id in the REST response.

这篇关于spring rest data序列化为一个关联作为相关实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆