Spring HATEOS - 如何投射基本类型 class 的所有属性?
Spring HATEOS - How to project all attribute of base type class?
给定 class 的投影,有没有办法告诉 Spring 包含 类型中定义的 class 的所有默认属性 的 Projection 注释 ?
给定 2 个实体 Class
@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"
}
}
}
有没有一种方法可以创建一个投影 return Client 的所有属性,而不必为 [=] 中的所有属性编写所有 getXXX 方法44=]客户端
@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)
}
这样我就可以在调用 http://127.0.0.1:8080/api/rest/Client/108?projection=inline 时在我的客户端 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"
}
},
"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"
}
}
}
}
您的 @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
转换为支持 _embedded
字段的 ClientResource
。看看 this question 如何做到这一点(我自己也用这个)
给定 class 的投影,有没有办法告诉 Spring 包含 类型中定义的 class 的所有默认属性 的 Projection 注释 ?
给定 2 个实体 Class
@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"
}
}
}
有没有一种方法可以创建一个投影 return Client 的所有属性,而不必为 [=] 中的所有属性编写所有 getXXX 方法44=]客户端
@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)
}
这样我就可以在调用 http://127.0.0.1:8080/api/rest/Client/108?projection=inline 时在我的客户端 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"
}
},
"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"
}
}
}
}
您的 @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
转换为支持 _embedded
字段的 ClientResource
。看看 this question 如何做到这一点(我自己也用这个)