春天HATEOAS - 如何项目基地型类的所有属性?

问题描述 投票:0回答:1

考虑到给定类的投影,是有没有办法告诉Spring包含在类型投影注释中定义的类的所有默认属性?

鉴于2实体类

@Entity 
@Data 
public class Client {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String nom;
    private String adresseLigne1;
    private String adresseLigne2;
    private String ville;

    @ManyToOne
    private Province province; 
    /* Many other attribute */

}

@Entity
@Data
public class Province {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String name;
}

并为每个存储库

@RepositoryRestResource(collectionResourceRel = "Client", path = "Client")
public interface ClientRepository extends PagingAndSortingRepository<Client, Long> {
    List<Client> findBy();
}

-

@RepositoryRestResource(collectionResourceRel = "Province", path = "Province")
public interface ProvinceRepository extends PagingAndSortingRepository<Province, Long> {
    List<Province> findByName(String name);
}

我获得客户端以下默认JSON:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  }
}

有没有一种方法来创建一个投影,将返回客户端的所有属性,而无需编写所有的getXXX方法对所有在客户端的属性

@Projection(name = "inlineProvince", types = { Client.class })
public interface ClientProjection {
    /* A way to tell the projection to include all of Client attribute */
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

这样我就可以得到省嵌在我的客户端调用JSON时http://127.0.0.1:8080/api/rest/Client/108?projection=inline

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  },
  "province" : {
    "name" : "Quebec"
  }
}

我发现,我可以这样做:

@Projection(name = "inline", types = { Client.class })
public interface ClientProjection {
    @Value("#{target}") 
    Client getClient();
    Province getProvince();  // This is the linked object I want to add to my json output as an in-line map (i.e have the behaviour as if it did not have it's own Repository)
}

但我同时获得客户及省为顶层元素。即省是不是在客户端:

{
  "province" : {
    "name" : "quebec"
  },
  "client" : {
      "nom" : "Mallowpond High",
      "adresseLigne1" : "895 Gonçal Burg",
      "adresseLigne2" : "Apt. 450",
      "ville" : "Lake Irenehaven",
      "_links" : {
        "self" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108"
        },
        "province" : {
          "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
        }
      }
  }
}
java spring spring-data-rest spring-hateoas
1个回答
0
投票

你的@RestRepositoryResource是生产被称为HAL格式。你所要求从HAL的规格偏离,我会建议留在标准(原因很明显)。

在HAL有嵌入关系到资源的支持。这将意味着你最终有一个_embedded场然后将持有基数1的集合,与在那里的省。这将是这个样子:

{
  "nom" : "Mallowpond High",
  "adresseLigne1" : "895 Gonçal Burg",
  "adresseLigne2" : "Apt. 450",
  "ville" : "Lake Irenehaven",
  "_links" : {
    "self" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108"
    },
    "province" : {
      "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
    }
  },
  "_embedded"{
     "provinces" : [{
        "name" : "Quebec",
        "_links" : {
          "self" : {
            "href" : "http://127.0.0.1:8080/api/rest/Client/108/province"
          }
        }
     }]
  }
}

不幸的是,这是不容易与Spring的@RepositoryRestResource支持,但还是比较容易实现的。您将需要添加一个ResourceAssembler和改造Client到支持的ClientResource领域_embedded。看看this question你如何能做到这一点(我用这个自己也)

© www.soinside.com 2019 - 2024. All rights reserved.